#include <iostream>
#include <string>
//------------------------ Common support:
namespace option {
template< class Name, class ValueType >
class Value
{
template< class N, class V >
friend V const& get( Value< N, V > const& );
template< class N, class V, class A >
friend void set( Value< N, V >&, A const& );
private:
ValueType value_;
public:
Value( ValueType const& v = ValueType() )
: value_( v )
{}
};
template< class Name, class ValueType >
ValueType const& get(
Value< Name, ValueType > const& option
)
{
return option.value_;
}
template< class Name, class ValueType, class ActualArgType >
void set(
Value< Name, ValueType >& option,
ActualArgType const& v
)
{
option.value_ = v;
}
} // namespace option
//------------------------ A particular options class & test program:
namespace name {
typedef struct width_namestruct* width;
typedef struct height_namestruct* height;
typedef struct title_namestruct* title;
} // namespace name
struct Options
: option::Value< name::width, int >
, option::Value< name::height, int >
, option::Value< name::title, std::string >
{
public:
template< class Name, class ActualArgType >
Options& with( ActualArgType const& v )
{
option::set<Name>( *this, v );
return *this;
}
};
int main()
{
using namespace std;
using namespace name;
using namespace option;
Options const o = Options()
.with<width>( 82 )
.with<height>( 19 )
.with<title>( "My button" );
cout << "Width = " << get<width>( o ) << endl;
cout << "Height = " << get<height>( o ) << endl;
cout << "Title = \"" << get<title>( o ) << "\"" << endl;
}