[ create a new paste ] login | about

Link: http://codepad.org/whgik1QJ    [ raw code | output | fork ]

C++, pasted on Jan 10:
#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 )
    {}

  typedef ValueType value_type;
  typedef Name name_type;
};

template< typename O, int I>
struct OpLayer : O {
  typedef char R[I];
  typedef R &Rf(typename O::name_type);
  operator Rf*();

  OpLayer( typename O::value_type const& v = typename O::value_type() )
    : O( 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;
}

struct none { 
  typedef none value_type;
  typedef none *name_type;
};

template<typename O1 = none, typename O2 = none, 
         typename O3 = none, typename O4 = none,
         typename O5 = none>
struct OptionList
  : 
  OpLayer<O1, 1>, 
  OpLayer<O2, 2>, 
  OpLayer<O3, 3>, 
  OpLayer<O4, 4>, 
  OpLayer<O5, 5> 
{
  template<int N, typename = void>
  struct index;
  template<typename V> struct index<1, V> { 
    typedef typename O1::value_type value_type; 
  };
  template<typename V> struct index<2, V> { 
    typedef typename O2::value_type value_type; 
  };
  template<typename V> struct index<3, V> { 
    typedef typename O2::value_type value_type; 
  };
  template<typename V> struct index<4, V> { 
    typedef typename O4::value_type value_type; 
  };
  template<typename V> struct index<5, V> { 
    typedef typename O5::value_type value_type; 
  };

  template<typename Name>
  struct name2val {
    typedef typename index<sizeof (*(OptionList*)0) (*(Name*)0)>::value_type type;
  };

  template< class Name >
  typename name2val<Name>::type const& get() const {
    return option::get<Name>(*this);
  }
};

}  // 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::OptionList< 
  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;
}


Output:
1
2
3
Width  = 82
Height = 19
Title  = "My button"


Create a new paste based on this one


Comments: