// Copyright (c) 2016-2021 Antony Polukhin // // 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 #include #include #include #include #include #include #include #include struct adl_hash { template std::size_t operator()(const T& val) const { using namespace boost; return hash_value(val); } }; struct comparable_struct { int i; short s; bool bl; int a,b,c,d,e,f; }; BOOST_PFR_FUNCTIONS_FOR(comparable_struct) template void test_some_comparable_struct() { Struct s1 {0, 1, false, 6,7,8,9,10,11}; Struct s2 = s1; Struct s3 {0, 1, false, 6,7,8,9,10,11111}; BOOST_TEST_EQ(s1, s2); BOOST_TEST(s1 <= s2); BOOST_TEST(s1 >= s2); BOOST_TEST(!(s1 != s2)); BOOST_TEST(!(s1 == s3)); BOOST_TEST(s1 != s3); BOOST_TEST(s1 < s3); BOOST_TEST(s3 > s2); BOOST_TEST(s1 <= s3); BOOST_TEST(s3 >= s2); std::cout << s1 << std::endl; Struct s4; std::stringstream ss; ss.exceptions ( std::ios::failbit); ss << s1; ss >> s4; std::cout << s4 << std::endl; BOOST_TEST_EQ(s1, s4); int i = 1, j = 2; BOOST_TEST_NE(i, j); } void test_comparable_struct() { test_some_comparable_struct(); } struct empty { operator std::string() { return "empty{}"; } }; BOOST_PFR_FUNCTIONS_FOR(empty) void test_empty_struct() { BOOST_TEST_EQ(empty{}, empty{}); } namespace foo { struct testing { bool b1, b2; int i; }; BOOST_PFR_FUNCTIONS_FOR(testing); } template void test_with_contatiners() { std::set t{ {true, true, 100}, {false, true, 100}, {true, false, 100}, {true, true, 101} }; BOOST_TEST(t.find({true, true, 100}) != t.end()); BOOST_TEST_EQ(t.count({true, true, 100}), 1u); std::unordered_set us(t.begin(), t.end()); BOOST_TEST_EQ(us.size(), t.size()); } void test_implicit_conversions() { std::stringstream ss; ss << std::true_type{}; BOOST_TEST_EQ(ss.str(), "1"); // Does not breaks implicit conversion ss.str(""); ss << empty{}; BOOST_TEST_EQ(ss.str(), "{}"); // Breaks implicit conversion for types marked with BOOST_PFR_FUNCTIONS_FOR } namespace { struct anonymous_comparable_struct { int i; short s; bool bl; int a,b,c,d,e,f; }; BOOST_PFR_FUNCTIONS_FOR(anonymous_comparable_struct) struct other_anonymous_struct { anonymous_comparable_struct a,b; }; BOOST_PFR_FUNCTIONS_FOR(other_anonymous_struct) } namespace std { template <> struct hash { std::size_t operator()(const anonymous_comparable_struct& val) const noexcept { return hash_value(val); } }; } namespace { void test_anonymous_comparable_struct() { test_some_comparable_struct(); } void test_nested_anonymous_comparable_struct() { other_anonymous_struct s1{ {0, 1, false, 6,7,8,9,10,11}, {0, 1, false, 6,7,8,9,10,11}, }; auto s2 = s1; BOOST_TEST_EQ(s1, s2); } } int main() { test_comparable_struct(); test_empty_struct(); test_with_contatiners>(); test_with_contatiners>(); test_implicit_conversions(); test_anonymous_comparable_struct(); test_nested_anonymous_comparable_struct(); return boost::report_errors(); }