#ifndef Rice__Arg_Impl_hpp_ #define Rice__Arg_Impl_hpp_ namespace Rice { //! Helper for defining default arguments of a method /*! This class exposes the ability to define the default values of a * wrapped method. Inspired by how Boost.Python handles keyword and * default arguments, the syntax is simple: * * \code * define_method( * "method", * &method, * (Arg("arg1"), Arg("arg2") = 3, Arg("arg3") = true) * ); * \endcode * * which means "for method &method, it takes 3 arguments * [arg1, arg2, arg3]. Of these arguments, arg2's default is 3 * and arg3's default is true. * * It may be required to explicitly cast the type of the default * value to prevent compilation errors. */ class Arg { public: //! Initialize a new Arg with the name of the argument /*! We require the name of the argument because 1) it makes code * easier to read and 2) hopefully Ruby gets keyword arguments * in the future and this means Rice will be ready for it. */ Arg(const char* name) : name_(name) , defaultValue(0) {} //! Copy Constructor Arg(const Arg& other) : name_(other.name()), defaultValue(other.defaultValue ? other.defaultValue->clone() : 0) {} virtual ~Arg() { if(defaultValue) { delete defaultValue; } } //! Set the default value for this Arg /*! Set the default value for this argument. * If this isn't called on this Arg, then this * Arg is required in the method call. * * \param val the value to store as default */ template Arg& operator=(Arg_Type val) { defaultValue = new type(val); return *this; } //! Check if this Arg has a default value associated with it bool hasDefaultValue() const { return defaultValue != 0; } //! Return the default value associated with this Arg /*! \return the type saved to this Arg */ template Arg_Type getDefaultValue() { return static_cast< type* >(defaultValue)->held; } //! Get the name of this Arg const char* name() const { return name_; } private: //! Name of the argument const char* name_; /** * The following is a stripped down version of * Boost.Any. */ class type_base { public: virtual ~type_base() {} virtual type_base* clone() const = 0; }; template class type : public type_base { public: type(Type value) :held(value) {} virtual ~type() { } virtual type_base* clone() const { return new type(held); } Type held; }; public: //! Our saved default value type_base* defaultValue; }; } #endif // Rice__Arg_Impl_hpp_