#include #include #include ////// implementation ////// namespace detail{ template struct Data{ explicit Data(T const& d) : data(d) {} protected: T data; }; template struct DoInherit : public State, public B::template Impl { explicit DoInherit(T const& d) : State(d){} }; template struct Inherit{ template struct apply{ typedef DoInherit type; }; }; } template class NewType : public boost::mpl::fold< Concepts, detail::Data, detail::Inherit > >::type { typedef typename boost::mpl::fold< Concepts, detail::Data, detail::Inherit > >::type Base; public: explicit NewType(T const& d) : Base(d){} struct Access{ template static T& data(P* d){ return static_cast(d)->data; } template static T const& data(P const* d){ return static_cast(d)->data; } template static NewType* this_(P* d){ return static_cast(d); } template static NewType* const& this_(P const* d){ return static_cast(d); } }; friend class DataAccess; }; ////////// some concepts //////////// struct NonCopyable{ template struct Impl{ public: Impl(){} private: Impl(Impl const&); }; }; struct NonAssignable{ template struct Impl{ private: Impl& operator=(Impl const&); }; }; struct Conversion{ template struct Impl{ public: operator T() const{ return NT::Access::data(this); } }; }; struct Equality{ template struct Impl{ public: bool operator==(NT const& lhs) const{ return NT::Access::data(this) == NT::Access::data(&lhs); } bool operator!=(NT const& lhs) const{ return NT::Access::data(this) != NT::Access::data(&lhs); } }; }; struct Ordering{ template struct Impl{ public: bool operator< (NT const& lhs) const{ return NT::Access::data(this) < NT::Access::data(&lhs); } bool operator<= (NT const& lhs) const{ return NT::Access::data(this) <= NT::Access::data(&lhs); } bool operator> (NT const& lhs) const{ return NT::Access::data(this) > NT::Access::data(&lhs); } bool operator>= (NT const& lhs) const{ return NT::Access::data(this) >= NT::Access::data(&lhs); } }; }; struct Additive{ template struct Impl{ public: NT operator+(NT const& lhs) const{ return NT(NT::Access::data(this) + NT::Access::data(&lhs)); } NT& operator+=(NT const& lhs){ NT::Access::data(this) += NT::Access::data(&lhs); return *NT::Access::this_(this); } }; }; /////////// some minor tests ///////// int main(){ typedef boost::mpl::vector Concepts; typedef NewType IdType; IdType id1(5u); IdType id2(5u); IdType id3(10u); //IdType id4 = id3; // NonCopyable IdType id5(0u); id5 = id3; // but assignable assert(id5 == id3); //id5 = 11u; // no conversion //IdType id6 = 11u; assert(id1 == id2); assert(id1 != id3); assert(id1 < id3); assert(id3 > id1); typedef NewType OtherIdType; OtherIdType oid1(5u); //NumberType oid2 = id1; // distinct types, even with same concepts and underlying type //assert(oid1 == id1); // no conversion }