/** * Copyright (C) 2018 T. Zachary Laine * * 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 "ill_formed.hpp" #include namespace bp = boost::parser; struct empty {}; struct int_ { int i; }; struct int_string { int i; std::string s; }; struct string_int { std::string s; int i; }; struct string_int_double { std::string s; int i; double d; }; struct string_int_double_priv { std::string s; private: [[maybe_unused]] int i; [[maybe_unused]] double d; }; struct string_int_double_no_copy_move { string_int_double_no_copy_move(string_int_double_no_copy_move const &) = delete; string_int_double_no_copy_move(string_int_double_no_copy_move &&) = delete; private: std::string s; [[maybe_unused]] int i; [[maybe_unused]] double d; }; struct employee { int age; std::string surname; std::string forename; double salary; }; int main() { // struct_arity { using bp::detail::struct_arity_v; static_assert(struct_arity_v == 0); static_assert(struct_arity_v == 1); static_assert(struct_arity_v == 2); static_assert(struct_arity_v == 2); static_assert(struct_arity_v == 3); // 1 due to the copy ctor. static_assert(struct_arity_v == 1); static_assert(struct_arity_v <= 0); } // is_struct_assignable { using bp::detail::is_struct_assignable_v; static_assert(!is_struct_assignable_v); static_assert(!is_struct_assignable_v>); static_assert(!is_struct_assignable_v>); static_assert(!is_struct_assignable_v>); static_assert(!is_struct_assignable_v>); static_assert( !is_struct_assignable_v>); static_assert(!is_struct_assignable_v< string_int_double, bp::tuple>); static_assert(!is_struct_assignable_v< string_int, bp::tuple>); static_assert(!is_struct_assignable_v< string_int_double_priv, bp::tuple>); static_assert(!is_struct_assignable_v< string_int_double_no_copy_move, bp::tuple>); static_assert( is_struct_assignable_v>); static_assert( is_struct_assignable_v>); static_assert( is_struct_assignable_v>); static_assert( is_struct_assignable_v>); static_assert(is_struct_assignable_v< string_int_double, bp::tuple>); static_assert(is_struct_assignable_v< string_int_double, bp::tuple>); } // is_tuple_assignable { using bp::detail::is_tuple_assignable_v; static_assert(!is_tuple_assignable_v); static_assert(!is_tuple_assignable_v, int>); static_assert(!is_tuple_assignable_v, void>); static_assert(!is_tuple_assignable_v, empty>); static_assert(!is_tuple_assignable_v, int_>); static_assert( !is_tuple_assignable_v, string_int>); static_assert( !is_tuple_assignable_v, string_int_double>); static_assert(!is_tuple_assignable_v< bp::tuple, string_int>); static_assert(!is_tuple_assignable_v< bp::tuple, string_int_double_priv>); static_assert(!is_tuple_assignable_v< bp::tuple, string_int_double_no_copy_move>); static_assert( std::is_aggregate_v && bp::detail::struct_arity_v == bp::detail::tuple_size_>); static_assert( is_tuple_assignable_v, int_string>); static_assert( is_tuple_assignable_v, int_string>); static_assert( is_tuple_assignable_v, string_int>); static_assert( is_tuple_assignable_v, string_int>); static_assert(is_tuple_assignable_v< bp::tuple, string_int_double>); static_assert(is_tuple_assignable_v< bp::tuple, string_int_double>); } // tuple_to_aggregate { { employee const expected_employee = {32, "Last", "First", 50000.0}; bp::tuple tup( 32, "Last", "First", 50000.0); employee assignee = bp::detail::tuple_to_aggregate( std::move(tup), std::make_integer_sequence< int, bp::detail::tuple_size_>()); BOOST_TEST(assignee.age == expected_employee.age); BOOST_TEST(assignee.surname == expected_employee.surname); BOOST_TEST(assignee.forename == expected_employee.forename); BOOST_TEST(assignee.salary == expected_employee.salary); // Verify move. BOOST_TEST(bp::get(tup, bp::llong<1>{}).empty()); BOOST_TEST(bp::get(tup, bp::llong<2>{}).empty()); } { employee const expected_employee = {32, "Last", "First", 50000.0}; bp::tuple tup( 32, "Last", "First", 50000.0); employee assignee = bp::detail::tuple_to_aggregate( std::move(tup), std::make_integer_sequence< int, bp::detail::tuple_size_>()); BOOST_TEST(assignee.age == expected_employee.age); BOOST_TEST(assignee.surname == expected_employee.surname); BOOST_TEST(assignee.forename == expected_employee.forename); BOOST_TEST(assignee.salary == expected_employee.salary); } } // tie_aggregate { employee assigner = {32, "Last", "First", 50000.0}; auto tup = bp::detail::tie_aggregate(assigner); BOOST_TEST(bp::get(tup, bp::llong<0>{}) == 32); BOOST_TEST(bp::get(tup, bp::llong<1>{}) == "Last"); BOOST_TEST(bp::get(tup, bp::llong<2>{}) == "First"); BOOST_TEST(bp::get(tup, bp::llong<3>{}) == 50000.0); } return boost::report_errors(); }