#include #include #include #include #include #include #include namespace core { namespace mpl = boost::mpl; namespace detail { template struct value_holder { BOOST_STATIC_ASSERT_MSG(boost::is_arithmetic::value, "T must be a fundamental type"); typedef BuiltInT builtin_type; typedef std::numeric_limits limits; constexpr value_holder() { } template constexpr value_holder(T d) : m_data(d) { } builtin_type m_data; }; } template struct operators : boost::less_than_comparable > > > > > { }; //////////////////////////////////////////////////////////////////////////// template struct my_type : detail::value_holder, operators > { typedef detail::value_holder base; typedef typename base::builtin_type builtin_type; typedef my_type type; // default constructor constexpr my_type() { } // copy constructor constexpr my_type(my_type const& other) : base(other.m_data) { } // copy constructor constexpr my_type(detail::value_holder const& other) : base(other.m_data) { } template constexpr my_type(T d) : base(d) { } builtin_type to_builtin() const { return base::m_data; } builtin_type& to_builtin() { return base::m_data; } bool operator<(my_type const& rhs) const { return to_builtin() < rhs.to_builtin(); } bool operator==(my_type const& rhs) const { return to_builtin() == rhs.to_builtin(); } my_type operator+=(my_type const& rhs) { to_builtin() += rhs.to_builtin(); return *this; } my_type operator-=(my_type const& rhs) { to_builtin() -= rhs.to_builtin(); return *this; } my_type operator*=(my_type const& rhs) { to_builtin() *= rhs.to_builtin(); return *this; } my_type operator/=(my_type const& rhs) { to_builtin() /= rhs.to_builtin(); return *this; } my_type operator-() const { return my_type(-to_builtin()); } template std::basic_ostream& print_on(std::basic_ostream& os) const { os << to_builtin(); return os; } }; //////////////////////////////////////////////////////////////////////////// namespace detail { template struct sqrt { typedef my_type source_type; typedef typename source_type::builtin_type builtin_type; static inline source_type apply(source_type const& value) { // XXX type promotion; rounding return std::sqrt(value.to_builtin()); } }; } // detail template static inline my_type sqrt(my_type const& value) { return detail::sqrt::apply(value); } //////////////////////////////////////////////////////////////////////////// template static inline std::basic_ostream& operator<<(std::basic_ostream& os, my_type const& v) { return v.print_on(os); } } //////////////////////////////////////////////////////////////////////////////// namespace kernel { template struct point { typedef core::my_type coordiante_type; coordiante_type x, y; }; } typedef kernel::point point_type; typedef kernel::point::coordiante_type coordinate_type; #include #include #include namespace bg = boost::geometry; // XXX BOOST_GEOMETRY_REGISTER_POINT_2D(point_type, point_type::coordiante_type, bg::cs::cartesian, x, y) BOOST_GEOMETRY_REGISTER_POINT_2D(kernel::point, kernel::point::coordiante_type, bg::cs::cartesian, x, y) int main() { point_type p1, p2; bg::assign_values(p1, 1, 1); bg::assign_values(p2, 2, 2); coordinate_type d = bg::distance(p1, p2); std::cout << "Distance: " << d << std::endl; }