2
0
mirror of https://github.com/boostorg/parser.git synced 2026-01-19 16:32:13 +00:00
Files
parser/test/aggr_tuple_assignment.cpp
2024-04-01 15:58:58 -05:00

238 lines
7.0 KiB
C++

/**
* 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 <boost/parser/tuple.hpp>
#include <boost/core/lightweight_test.hpp>
#include "ill_formed.hpp"
#include <string>
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<empty> == 0);
static_assert(struct_arity_v<int_> == 1);
static_assert(struct_arity_v<int_string> == 2);
static_assert(struct_arity_v<string_int> == 2);
static_assert(struct_arity_v<string_int_double> == 3);
// 1 due to the copy ctor.
static_assert(struct_arity_v<string_int_double_priv> == 1);
static_assert(struct_arity_v<string_int_double_no_copy_move> <= 0);
}
// is_struct_assignable
{
using bp::detail::is_struct_assignable_v;
static_assert(!is_struct_assignable_v<void, void>);
static_assert(!is_struct_assignable_v<int, bp::tuple<int, std::string>>);
static_assert(!is_struct_assignable_v<void, bp::tuple<int, std::string>>);
static_assert(!is_struct_assignable_v<empty, bp::tuple<int, std::string>>);
static_assert(!is_struct_assignable_v<int_, bp::tuple<int, std::string>>);
static_assert(
!is_struct_assignable_v<string_int, bp::tuple<int, std::string>>);
static_assert(!is_struct_assignable_v<
string_int_double,
bp::tuple<std::string, int>>);
static_assert(!is_struct_assignable_v<
string_int,
bp::tuple<std::string, int, double>>);
static_assert(!is_struct_assignable_v<
string_int_double_priv,
bp::tuple<std::string, int, double>>);
static_assert(!is_struct_assignable_v<
string_int_double_no_copy_move,
bp::tuple<std::string, int, double>>);
static_assert(
is_struct_assignable_v<int_string, bp::tuple<int, std::string>>);
static_assert(
is_struct_assignable_v<int_string, bp::tuple<short, char const *>>);
static_assert(
is_struct_assignable_v<string_int, bp::tuple<std::string, int>>);
static_assert(
is_struct_assignable_v<string_int, bp::tuple<char const *, short>>);
static_assert(is_struct_assignable_v<
string_int_double,
bp::tuple<std::string, int, double>>);
static_assert(is_struct_assignable_v<
string_int_double,
bp::tuple<char const *, short, float>>);
}
// is_tuple_assignable
{
using bp::detail::is_tuple_assignable_v;
static_assert(!is_tuple_assignable_v<void, void>);
static_assert(!is_tuple_assignable_v<bp::tuple<int, std::string>, int>);
static_assert(!is_tuple_assignable_v<bp::tuple<int, std::string>, void>);
static_assert(!is_tuple_assignable_v<bp::tuple<int, std::string>, empty>);
static_assert(!is_tuple_assignable_v<bp::tuple<int, std::string>, int_>);
static_assert(
!is_tuple_assignable_v<bp::tuple<int, std::string>, string_int>);
static_assert(
!is_tuple_assignable_v<bp::tuple<std::string, int>, string_int_double>);
static_assert(!is_tuple_assignable_v<
bp::tuple<std::string, int, double>,
string_int>);
static_assert(!is_tuple_assignable_v<
bp::tuple<std::string, int, double>,
string_int_double_priv>);
static_assert(!is_tuple_assignable_v<
bp::tuple<std::string, int, double>,
string_int_double_no_copy_move>);
static_assert(
std::is_aggregate_v<int_string> &&
bp::detail::struct_arity_v<int_string> ==
bp::detail::tuple_size_<bp::tuple<int, std::string>>);
static_assert(
is_tuple_assignable_v<bp::tuple<int, std::string>, int_string>);
static_assert(
is_tuple_assignable_v<bp::tuple<short, std::string>, int_string>);
static_assert(
is_tuple_assignable_v<bp::tuple<std::string, int>, string_int>);
static_assert(
is_tuple_assignable_v<bp::tuple<std::string, short>, string_int>);
static_assert(is_tuple_assignable_v<
bp::tuple<std::string, int, double>,
string_int_double>);
static_assert(is_tuple_assignable_v<
bp::tuple<std::string, short, float>,
string_int_double>);
}
// tuple_to_aggregate
{
{
employee const expected_employee = {32, "Last", "First", 50000.0};
bp::tuple<int, std::string, std::string, double> tup(
32, "Last", "First", 50000.0);
employee assignee = bp::detail::tuple_to_aggregate<employee>(
std::move(tup),
std::make_integer_sequence<
int,
bp::detail::tuple_size_<decltype(tup)>>());
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<int, char const *, char const *, double> tup(
32, "Last", "First", 50000.0);
employee assignee = bp::detail::tuple_to_aggregate<employee>(
std::move(tup),
std::make_integer_sequence<
int,
bp::detail::tuple_size_<decltype(tup)>>());
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();
}