/*============================================================================= Copyright (c) 2016 Lee Clagett Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ==============================================================================*/ #include #include namespace test_detail { struct convertible { convertible() : value_() {} convertible(int value) : value_(value) {} int value_; }; bool operator==(convertible const& lhs, convertible const& rhs) { return lhs.value_ == rhs.value_; } bool operator!=(convertible const& lhs, convertible const& rhs) { return lhs.value_ != rhs.value_; } // Testing conversion at function call allows for testing mutable lvalue, // const lvalue, and rvalue as the source. mpl::identity prevents deduction template T implicit_construct(typename boost::mpl::identity::type source) { return source; } template bool run(Source const& source, Expected const& expected) { return F()(source, expected); } template bool run(Source const& source) { return run(source, source); } template struct can_rvalue_implicit_construct { template bool operator()(Source const& source, Expected const& expected) const { return expected == implicit_construct(implicit_construct(source)); } }; template struct can_lvalue_implicit_construct { template bool operator()(Source source, Expected const& expected) const { return expected == implicit_construct(source); } }; template struct can_const_lvalue_implicit_construct { template bool operator()(Source const& source, Expected const& expected) const { return expected == implicit_construct(source); } }; template struct can_implicit_construct { template bool operator()(Source const& source, Expected const& expected) const { return run< can_rvalue_implicit_construct >(source, expected) && run< can_lvalue_implicit_construct >(source, expected) && run< can_const_lvalue_implicit_construct >(source, expected); } }; template struct can_rvalue_construct { template bool operator()(Source const& source, Expected const& expected) const { return expected == T(implicit_construct(source)); } }; template struct can_lvalue_construct { template bool operator()(Source source, Expected const& expected) const { return expected == T(source); } }; template struct can_const_lvalue_construct { template bool operator()(Source const& source, Expected const& expected) const { return expected == T(source); } }; template struct can_construct { template bool operator()(Source const& source, Expected const& expected) const { return run< can_rvalue_construct >(source, expected) && run< can_lvalue_construct >(source, expected) && run< can_const_lvalue_construct >(source, expected); } }; template struct can_rvalue_assign { template bool operator()(Source const& source, Expected const& expected) const { bool result = true; { T seq; result &= (seq == expected || seq != expected); seq = implicit_construct(source); result &= (seq == expected); } return result; } }; template struct can_lvalue_assign { template bool operator()(Source source, Expected const& expected) const { bool result = true; { T seq; result &= (seq == expected || seq != expected); seq = source; result &= (seq == expected); } return result; } }; template struct can_const_lvalue_assign { template bool operator()(Source const& source, Expected const& expected) const { bool result = true; { T seq; result &= (seq == expected || seq != expected); seq = source; result &= (seq == expected); } return result; } }; template struct can_assign { template bool operator()(Source const& source, Expected const& expected) const { return run< can_rvalue_assign >(source, expected) && run< can_lvalue_assign >(source, expected) && run< can_const_lvalue_assign >(source, expected); } }; template struct can_copy { template bool operator()(Source const& source, Expected const& expected) const { return run< can_construct >(source, expected) && run< can_implicit_construct >(source, expected) && run< can_assign >(source, expected); } }; } // test_detail