/* @copyright Louis Dionne 2014 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) */ #include #include #include #include namespace take2 { using boost::hana::datatype_t; using boost::hana::true_; using boost::hana::false_; template constexpr auto has_common_type = false_; template constexpr auto has_common_type() : std::declval()), int{0}) > = true_; template struct Comparable; BOOST_HANA_CONSTEXPR_LAMBDA auto equal = [](auto x, auto y) { return Comparable, datatype_t>:: equal_impl(x, y); }; BOOST_HANA_CONSTEXPR_LAMBDA auto not_equal = [](auto x, auto y) { return Comparable, datatype_t>:: not_equal_impl(x, y); }; struct fall_back_comparable { template static constexpr auto equal_impl(X x, Y y, std::enable_if_t< !std::is_same{} && has_common_type>* = 0) { using C = std::common_type_t; return equal(C{x}, C{y}); } template static constexpr auto equal_impl(X x, Y y, std::enable_if_t< !std::is_same{} && !has_common_type>* = 0) { return false_; } template static constexpr auto equal_impl(X x, Y y, std::enable_if_t< std::is_same{}>* = 0) { static_assert((y, void(), false_), "trying to compare two objects of an incomparable type"); return false_; } template static constexpr auto not_equal_impl(X x, Y y) { return !equal_impl(x, y); } }; template struct Comparable : fall_back_comparable { }; template