2
0
mirror of https://github.com/boostorg/parser.git synced 2026-01-21 05:02:14 +00:00
Files
parser/test/tuple_aggregate.cpp
Zach Laine f34f096c66 Add logic to repeat_parser analogous to the logic in seq_parser, to enable
implicit tuple <-> struct conversions.

Fixes #47.
2024-01-04 18:38:44 -06:00

1094 lines
43 KiB
C++

/**
* Copyright (C) 2023 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/parser.hpp>
#include <gtest/gtest.h>
using namespace boost::parser;
struct s0_rule_tag
{};
struct s1_rule_a_tag
{};
struct s1_rule_b_tag
{};
struct s2_rule_a_tag
{};
struct s2_rule_b_tag
{};
struct s0
{
int i_;
std::string str_;
std::vector<int> vec_;
};
using s0_tuple = tuple<int, std::string, std::vector<int>>;
auto s0_parser = "s0" >> int_ >> lexeme[+(char_ - ' ')] >> *int_;
callback_rule<s0_rule_tag, s0> s0_rule = "s0_rule";
auto s0_rule_def = s0_parser;
struct s1
{
int i_;
std::variant<std::string, double> str_;
std::vector<int> vec_;
};
using s1_tuple =
tuple<int, std::variant<std::string, double>, std::vector<int>>;
auto s1_parser_a = "s1" >> int_ >> lexeme[+(char_ - ' ')] >> *int_;
auto s1_parser_b = "s1" >> int_ >> double_ >> *int_;
callback_rule<s1_rule_a_tag, s1> s1_rule_a = "s1_rule_a";
callback_rule<s1_rule_b_tag, s1> s1_rule_b = "s1_rule_b";
auto s1_rule_a_def = s1_parser_a;
auto s1_rule_b_def = s1_parser_b;
struct s2
{
int i_;
std::string str_;
std::optional<std::vector<int>> vec_;
};
using s2_tuple = tuple<int, std::string, std::optional<std::vector<int>>>;
auto s2_parser_a = "s2" >> int_ >> lexeme[+(char_ - ' ')] >> *int_;
auto s2_parser_b = "s2" >> int_ >> lexeme[+(char_ - ' ')] >> -+int_;
callback_rule<s2_rule_a_tag, s2> s2_rule_a = "s2_rule_a";
callback_rule<s2_rule_b_tag, s2> s2_rule_b = "s2_rule_b";
auto s2_rule_a_def = s2_parser_a;
auto s2_rule_b_def = s2_parser_b;
BOOST_PARSER_DEFINE_RULES(s0_rule, s1_rule_a, s1_rule_b, s2_rule_a, s2_rule_b);
struct s0_like
{
int64_t i_;
std::string str_;
std::vector<int> vec_;
};
TEST(struct_tuple, seq_parser_struct_rule)
{
////////////////////////////////////////////////////////////////////////////
// Parse-generated attribute.
{
std::optional<s0> result = parse("s0 42 text 1 2 3", s0_rule, ws);
EXPECT_TRUE(result);
s0 & struct_ = *result;
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}), "text");
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
{
std::optional<s1> const result =
parse("s1 42 text 1 2 3", s1_rule_a, ws);
EXPECT_TRUE(result);
s1 const & struct_ = *result;
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}).index(), 0u);
EXPECT_EQ(std::get<0>(get(struct_, llong<1>{})), "text");
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
{
std::optional<s1> const result =
parse("s1 42 13.0 1 2 3", s1_rule_b, ws);
EXPECT_TRUE(result);
s1 const & struct_ = *result;
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}).index(), 1u);
EXPECT_EQ(std::get<1>(get(struct_, llong<1>{})), 13.0);
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
{
std::optional<s2> const result =
parse("s2 42 text 1 2 3", s2_rule_a, ws);
EXPECT_TRUE(result);
s2 const & struct_ = *result;
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}), "text");
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
{
std::optional<s2> const result =
parse("s2 42 text 1 2 3", s2_rule_b, ws);
EXPECT_TRUE(result);
s2 const & struct_ = *result;
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}), "text");
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
// Use the rule as part of a larger parse.
{
std::optional<tuple<int, s0>> const result =
parse("99 s0 42 text 1 2 3", int_ >> s0_rule, ws);
auto i_ = get(*result, llong<0>{});
EXPECT_EQ(i_, 99);
auto struct_ = get(*result, llong<1>{});
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}), "text");
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
{
std::optional<tuple<int, s1>> const result =
parse("99 s1 42 text 1 2 3", int_ >> s1_rule_a, ws);
auto i_ = get(*result, llong<0>{});
EXPECT_EQ(i_, 99);
auto struct_ = get(*result, llong<1>{});
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}).index(), 0u);
EXPECT_EQ(std::get<0>(get(struct_, llong<1>{})), "text");
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
{
std::optional<tuple<int, s1>> const result =
parse("99 s1 42 13.0 1 2 3", int_ >> s1_rule_b, ws);
auto i_ = get(*result, llong<0>{});
EXPECT_EQ(i_, 99);
auto struct_ = get(*result, llong<1>{});
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}).index(), 1u);
EXPECT_EQ(std::get<1>(get(struct_, llong<1>{})), 13.0);
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
{
std::optional<tuple<int, s2>> const result =
parse("99 s2 42 text 1 2 3", int_ >> s2_rule_a, ws);
auto i_ = get(*result, llong<0>{});
EXPECT_EQ(i_, 99);
auto struct_ = get(*result, llong<1>{});
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}), "text");
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
{
std::optional<tuple<int, s2>> const result =
parse("99 s2 42 text 1 2 3", int_ >> s2_rule_b, ws);
auto i_ = get(*result, llong<0>{});
EXPECT_EQ(i_, 99);
auto struct_ = get(*result, llong<1>{});
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}), "text");
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
////////////////////////////////////////////////////////////////////////////
// Pass attribute to parse.
{
s0 struct_;
EXPECT_TRUE(parse("s0 42 text 1 2 3", s0_rule, ws, struct_));
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}), "text");
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
#if 0 // TODO: Do we want to support this? Probably not. It would require us
// to make an operation equivalent to s0_like::operator=(s0 const &)
// work.
{
s0_like struct_;
EXPECT_TRUE(parse("s0 42 text 1 2 3", s0_rule, ws, struct_));
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}), "text");
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
#endif
{
s1 struct_;
EXPECT_TRUE(parse("s1 42 text 1 2 3", s1_rule_a, ws, struct_));
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}).index(), 0u);
EXPECT_EQ(std::get<0>(get(struct_, llong<1>{})), "text");
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
{
s1 struct_;
EXPECT_TRUE(parse("s1 42 13.0 1 2 3", s1_rule_b, ws, struct_));
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}).index(), 1u);
EXPECT_EQ(std::get<1>(get(struct_, llong<1>{})), 13.0);
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
{
s2 struct_;
EXPECT_TRUE(parse("s2 42 text 1 2 3", s2_rule_a, ws, struct_));
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}), "text");
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
{
s2 struct_;
EXPECT_TRUE(parse("s2 42 text 1 2 3", s2_rule_b, ws, struct_));
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}), "text");
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
// Use the rule as part of a larger parse.
{
tuple<int, s0> result;
EXPECT_TRUE(parse("99 s0 42 text 1 2 3", int_ >> s0_rule, ws, result));
auto i_ = get(result, llong<0>{});
EXPECT_EQ(i_, 99);
auto struct_ = get(result, llong<1>{});
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}), "text");
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
{
tuple<int, s1> result;
EXPECT_TRUE(parse("99 s1 42 text 1 2 3", int_ >> s1_rule_a, ws, result));
auto i_ = get(result, llong<0>{});
EXPECT_EQ(i_, 99);
auto struct_ = get(result, llong<1>{});
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}).index(), 0u);
EXPECT_EQ(std::get<0>(get(struct_, llong<1>{})), "text");
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
{
tuple<int, s1> result;
EXPECT_TRUE(parse("99 s1 42 13.0 1 2 3", int_ >> s1_rule_b, ws, result));
auto i_ = get(result, llong<0>{});
EXPECT_EQ(i_, 99);
auto struct_ = get(result, llong<1>{});
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}).index(), 1u);
EXPECT_EQ(std::get<1>(get(struct_, llong<1>{})), 13.0);
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
{
tuple<int, s2> result;
EXPECT_TRUE(parse("99 s2 42 text 1 2 3", int_ >> s2_rule_a, ws, result));
auto i_ = get(result, llong<0>{});
EXPECT_EQ(i_, 99);
auto struct_ = get(result, llong<1>{});
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}), "text");
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
{
tuple<int, s2> result;
EXPECT_TRUE(parse("99 s2 42 text 1 2 3", int_ >> s2_rule_b, ws, result));
auto i_ = get(result, llong<0>{});
EXPECT_EQ(i_, 99);
auto struct_ = get(result, llong<1>{});
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}), "text");
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
}
TEST(struct_tuple, repeated_seq_parser_struct_rule)
{
////////////////////////////////////////////////////////////////////////////
// Parse-generated attribute.
{
std::optional<std::vector<s0>> result =
parse("s0 42 text 1 2 3 s0 41 texty 1 3 2", *s0_rule, ws);
EXPECT_TRUE(result);
std::vector<s0> & structs_ = *result;
EXPECT_EQ(get(structs_[0], llong<0>{}), 42);
EXPECT_EQ(get(structs_[0], llong<1>{}), "text");
EXPECT_EQ(get(structs_[0], llong<2>{}), std::vector<int>({1, 2, 3}));
EXPECT_EQ(get(structs_[1], llong<0>{}), 41);
EXPECT_EQ(get(structs_[1], llong<1>{}), "texty");
EXPECT_EQ(get(structs_[1], llong<2>{}), std::vector<int>({1, 3, 2}));
}
{
std::optional<std::vector<s1>> const result =
parse("s1 42 text 1 2 3 s1 41 texty 1 3 2", *s1_rule_a, ws);
EXPECT_TRUE(result);
std::vector<s1> const & structs_ = *result;
EXPECT_EQ(get(structs_[0], llong<0>{}), 42);
EXPECT_EQ(get(structs_[0], llong<1>{}).index(), 0u);
EXPECT_EQ(std::get<0>(get(structs_[0], llong<1>{})), "text");
EXPECT_EQ(get(structs_[0], llong<2>{}), std::vector<int>({1, 2, 3}));
EXPECT_EQ(get(structs_[1], llong<0>{}), 41);
EXPECT_EQ(get(structs_[1], llong<1>{}).index(), 0u);
EXPECT_EQ(std::get<0>(get(structs_[1], llong<1>{})), "texty");
EXPECT_EQ(get(structs_[1], llong<2>{}), std::vector<int>({1, 3, 2}));
}
{
std::optional<std::vector<s1>> const result =
parse("s1 42 13.0 1 2 3 s1 41 12.0 1 3 2", *s1_rule_b, ws);
EXPECT_TRUE(result);
std::vector<s1> const & structs_ = *result;
EXPECT_EQ(get(structs_[0], llong<0>{}), 42);
EXPECT_EQ(get(structs_[0], llong<1>{}).index(), 1u);
EXPECT_EQ(std::get<1>(get(structs_[0], llong<1>{})), 13.0);
EXPECT_EQ(get(structs_[0], llong<2>{}), std::vector<int>({1, 2, 3}));
EXPECT_EQ(get(structs_[1], llong<0>{}), 41);
EXPECT_EQ(get(structs_[1], llong<1>{}).index(), 1u);
EXPECT_EQ(std::get<1>(get(structs_[1], llong<1>{})), 12.0);
EXPECT_EQ(get(structs_[1], llong<2>{}), std::vector<int>({1, 3, 2}));
}
{
std::optional<std::vector<s2>> const result =
parse("s2 42 text 1 2 3 s2 41 texty 1 3 2", *s2_rule_a, ws);
EXPECT_TRUE(result);
std::vector<s2> const & structs_ = *result;
EXPECT_EQ(get(structs_[0], llong<0>{}), 42);
EXPECT_EQ(get(structs_[0], llong<1>{}), "text");
EXPECT_EQ(get(structs_[0], llong<2>{}), std::vector<int>({1, 2, 3}));
EXPECT_EQ(get(structs_[1], llong<0>{}), 41);
EXPECT_EQ(get(structs_[1], llong<1>{}), "texty");
EXPECT_EQ(get(structs_[1], llong<2>{}), std::vector<int>({1, 3, 2}));
}
{
std::optional<std::vector<s2>> const result =
parse("s2 42 text 1 2 3 s2 41 texty 1 3 2", *s2_rule_b, ws);
EXPECT_TRUE(result);
std::vector<s2> const & structs_ = *result;
EXPECT_EQ(get(structs_[0], llong<0>{}), 42);
EXPECT_EQ(get(structs_[0], llong<1>{}), "text");
EXPECT_EQ(get(structs_[0], llong<2>{}), std::vector<int>({1, 2, 3}));
EXPECT_EQ(get(structs_[1], llong<0>{}), 41);
EXPECT_EQ(get(structs_[1], llong<1>{}), "texty");
EXPECT_EQ(get(structs_[1], llong<2>{}), std::vector<int>({1, 3, 2}));
}
// Use the rule as part of a larger parse.
{
std::optional<tuple<int, std::vector<s0>>> const result =
parse("99 s0 42 text 1 2 3 s0 41 texty 1 3 2", int_ >> *s0_rule, ws);
auto i_ = get(*result, llong<0>{});
EXPECT_EQ(i_, 99);
auto structs_ = get(*result, llong<1>{});
EXPECT_EQ(get(structs_[0], llong<0>{}), 42);
EXPECT_EQ(get(structs_[0], llong<1>{}), "text");
EXPECT_EQ(get(structs_[0], llong<2>{}), std::vector<int>({1, 2, 3}));
EXPECT_EQ(get(structs_[1], llong<0>{}), 41);
EXPECT_EQ(get(structs_[1], llong<1>{}), "texty");
EXPECT_EQ(get(structs_[1], llong<2>{}), std::vector<int>({1, 3, 2}));
}
{
std::optional<tuple<int, std::vector<s1>>> const result =
parse("99 s1 42 text 1 2 3 s1 41 texty 1 3 2", int_ >> *s1_rule_a, ws);
auto i_ = get(*result, llong<0>{});
EXPECT_EQ(i_, 99);
auto structs_ = get(*result, llong<1>{});
EXPECT_EQ(get(structs_[0], llong<0>{}), 42);
EXPECT_EQ(get(structs_[0], llong<1>{}).index(), 0u);
EXPECT_EQ(std::get<0>(get(structs_[0], llong<1>{})), "text");
EXPECT_EQ(get(structs_[0], llong<2>{}), std::vector<int>({1, 2, 3}));
EXPECT_EQ(get(structs_[1], llong<0>{}), 41);
EXPECT_EQ(get(structs_[1], llong<1>{}).index(), 0u);
EXPECT_EQ(std::get<0>(get(structs_[1], llong<1>{})), "texty");
EXPECT_EQ(get(structs_[1], llong<2>{}), std::vector<int>({1, 3, 2}));
}
{
std::optional<tuple<int, std::vector<s1>>> const result =
parse("99 s1 42 13.0 1 2 3 s1 41 12.0 1 3 2", int_ >> *s1_rule_b, ws);
auto i_ = get(*result, llong<0>{});
EXPECT_EQ(i_, 99);
auto structs_ = get(*result, llong<1>{});
EXPECT_EQ(get(structs_[0], llong<0>{}), 42);
EXPECT_EQ(get(structs_[0], llong<1>{}).index(), 1u);
EXPECT_EQ(std::get<1>(get(structs_[0], llong<1>{})), 13.0);
EXPECT_EQ(get(structs_[0], llong<2>{}), std::vector<int>({1, 2, 3}));
EXPECT_EQ(get(structs_[1], llong<0>{}), 41);
EXPECT_EQ(get(structs_[1], llong<1>{}).index(), 1u);
EXPECT_EQ(std::get<1>(get(structs_[1], llong<1>{})), 12.0);
EXPECT_EQ(get(structs_[1], llong<2>{}), std::vector<int>({1, 3, 2}));
}
{
std::optional<tuple<int, std::vector<s2>>> const result =
parse("99 s2 42 text 1 2 3 s2 41 texty 1 3 2", int_ >> *s2_rule_a, ws);
auto i_ = get(*result, llong<0>{});
EXPECT_EQ(i_, 99);
auto structs_ = get(*result, llong<1>{});
EXPECT_EQ(get(structs_[0], llong<0>{}), 42);
EXPECT_EQ(get(structs_[0], llong<1>{}), "text");
EXPECT_EQ(get(structs_[0], llong<2>{}), std::vector<int>({1, 2, 3}));
EXPECT_EQ(get(structs_[1], llong<0>{}), 41);
EXPECT_EQ(get(structs_[1], llong<1>{}), "texty");
EXPECT_EQ(get(structs_[1], llong<2>{}), std::vector<int>({1, 3, 2}));
}
{
std::optional<tuple<int, std::vector<s2>>> const result =
parse("99 s2 42 text 1 2 3 s2 41 texty 1 3 2", int_ >> *s2_rule_b, ws);
auto i_ = get(*result, llong<0>{});
EXPECT_EQ(i_, 99);
auto structs_ = get(*result, llong<1>{});
EXPECT_EQ(get(structs_[0], llong<0>{}), 42);
EXPECT_EQ(get(structs_[0], llong<1>{}), "text");
EXPECT_EQ(get(structs_[0], llong<2>{}), std::vector<int>({1, 2, 3}));
EXPECT_EQ(get(structs_[1], llong<0>{}), 41);
EXPECT_EQ(get(structs_[1], llong<1>{}), "texty");
EXPECT_EQ(get(structs_[1], llong<2>{}), std::vector<int>({1, 3, 2}));
}
////////////////////////////////////////////////////////////////////////////
// Pass attribute to parse.
{
std::vector<s0> structs_;
EXPECT_TRUE(parse(
"s0 42 text 1 2 3 s0 41 texty 1 3 2", *s0_rule, ws, structs_));
EXPECT_EQ(get(structs_[0], llong<0>{}), 42);
EXPECT_EQ(get(structs_[0], llong<1>{}), "text");
EXPECT_EQ(get(structs_[0], llong<2>{}), std::vector<int>({1, 2, 3}));
EXPECT_EQ(get(structs_[1], llong<0>{}), 41);
EXPECT_EQ(get(structs_[1], llong<1>{}), "texty");
EXPECT_EQ(get(structs_[1], llong<2>{}), std::vector<int>({1, 3, 2}));
}
{
std::vector<s1> structs_;
EXPECT_TRUE(parse(
"s1 42 text 1 2 3 s1 41 texty 1 3 2", *s1_rule_a, ws, structs_));
EXPECT_EQ(get(structs_[0], llong<0>{}), 42);
EXPECT_EQ(get(structs_[0], llong<1>{}).index(), 0u);
EXPECT_EQ(std::get<0>(get(structs_[0], llong<1>{})), "text");
EXPECT_EQ(get(structs_[0], llong<2>{}), std::vector<int>({1, 2, 3}));
EXPECT_EQ(get(structs_[1], llong<0>{}), 41);
EXPECT_EQ(get(structs_[1], llong<1>{}).index(), 0u);
EXPECT_EQ(std::get<0>(get(structs_[1], llong<1>{})), "texty");
EXPECT_EQ(get(structs_[1], llong<2>{}), std::vector<int>({1, 3, 2}));
}
{
std::vector<s1> structs_;
EXPECT_TRUE(parse(
"s1 42 13.0 1 2 3 s1 41 12.0 1 3 2", *s1_rule_b, ws, structs_));
EXPECT_EQ(get(structs_[0], llong<0>{}), 42);
EXPECT_EQ(get(structs_[0], llong<1>{}).index(), 1u);
EXPECT_EQ(std::get<1>(get(structs_[0], llong<1>{})), 13.0);
EXPECT_EQ(get(structs_[0], llong<2>{}), std::vector<int>({1, 2, 3}));
EXPECT_EQ(get(structs_[1], llong<0>{}), 41);
EXPECT_EQ(get(structs_[1], llong<1>{}).index(), 1u);
EXPECT_EQ(std::get<1>(get(structs_[1], llong<1>{})), 12.0);
EXPECT_EQ(get(structs_[1], llong<2>{}), std::vector<int>({1, 3, 2}));
}
{
std::vector<s2> structs_;
EXPECT_TRUE(parse(
"s2 42 text 1 2 3 s2 41 texty 1 3 2", *s2_rule_a, ws, structs_));
EXPECT_EQ(get(structs_[0], llong<0>{}), 42);
EXPECT_EQ(get(structs_[0], llong<1>{}), "text");
EXPECT_EQ(get(structs_[0], llong<2>{}), std::vector<int>({1, 2, 3}));
EXPECT_EQ(get(structs_[1], llong<0>{}), 41);
EXPECT_EQ(get(structs_[1], llong<1>{}), "texty");
EXPECT_EQ(get(structs_[1], llong<2>{}), std::vector<int>({1, 3, 2}));
}
{
std::vector<s2> structs_;
EXPECT_TRUE(parse(
"s2 42 text 1 2 3 s2 41 texty 1 3 2", *s2_rule_b, ws, structs_));
EXPECT_EQ(get(structs_[0], llong<0>{}), 42);
EXPECT_EQ(get(structs_[0], llong<1>{}), "text");
EXPECT_EQ(get(structs_[0], llong<2>{}), std::vector<int>({1, 2, 3}));
EXPECT_EQ(get(structs_[1], llong<0>{}), 41);
EXPECT_EQ(get(structs_[1], llong<1>{}), "texty");
EXPECT_EQ(get(structs_[1], llong<2>{}), std::vector<int>({1, 3, 2}));
}
// Use the rule as part of a larger parse.
{
tuple<int, std::vector<s0>> result;
EXPECT_TRUE(parse(
"99 s0 42 text 1 2 3 s0 41 texty 1 3 2",
int_ >> *s0_rule,
ws,
result));
auto i_ = get(result, llong<0>{});
EXPECT_EQ(i_, 99);
auto structs_ = get(result, llong<1>{});
EXPECT_EQ(get(structs_[0], llong<0>{}), 42);
EXPECT_EQ(get(structs_[0], llong<1>{}), "text");
EXPECT_EQ(get(structs_[0], llong<2>{}), std::vector<int>({1, 2, 3}));
EXPECT_EQ(get(structs_[1], llong<0>{}), 41);
EXPECT_EQ(get(structs_[1], llong<1>{}), "texty");
EXPECT_EQ(get(structs_[1], llong<2>{}), std::vector<int>({1, 3, 2}));
}
{
tuple<int, std::vector<s1>> result;
EXPECT_TRUE(parse(
"99 s1 42 text 1 2 3 s1 41 texty 1 3 2",
int_ >> *s1_rule_a,
ws,
result));
auto i_ = get(result, llong<0>{});
EXPECT_EQ(i_, 99);
auto structs_ = get(result, llong<1>{});
EXPECT_EQ(get(structs_[0], llong<0>{}), 42);
EXPECT_EQ(get(structs_[0], llong<1>{}).index(), 0u);
EXPECT_EQ(std::get<0>(get(structs_[0], llong<1>{})), "text");
EXPECT_EQ(get(structs_[0], llong<2>{}), std::vector<int>({1, 2, 3}));
EXPECT_EQ(get(structs_[1], llong<0>{}), 41);
EXPECT_EQ(get(structs_[1], llong<1>{}).index(), 0u);
EXPECT_EQ(std::get<0>(get(structs_[1], llong<1>{})), "texty");
EXPECT_EQ(get(structs_[1], llong<2>{}), std::vector<int>({1, 3, 2}));
}
{
tuple<int, std::vector<s1>> result;
EXPECT_TRUE(parse(
"99 s1 42 13.0 1 2 3 s1 41 12.0 1 3 2",
int_ >> *s1_rule_b,
ws,
result));
auto i_ = get(result, llong<0>{});
EXPECT_EQ(i_, 99);
auto structs_ = get(result, llong<1>{});
EXPECT_EQ(get(structs_[0], llong<0>{}), 42);
EXPECT_EQ(get(structs_[0], llong<1>{}).index(), 1u);
EXPECT_EQ(std::get<1>(get(structs_[0], llong<1>{})), 13.0);
EXPECT_EQ(get(structs_[0], llong<2>{}), std::vector<int>({1, 2, 3}));
EXPECT_EQ(get(structs_[1], llong<0>{}), 41);
EXPECT_EQ(get(structs_[1], llong<1>{}).index(), 1u);
EXPECT_EQ(std::get<1>(get(structs_[1], llong<1>{})), 12.0);
EXPECT_EQ(get(structs_[1], llong<2>{}), std::vector<int>({1, 3, 2}));
}
{
tuple<int, std::vector<s2>> result;
EXPECT_TRUE(parse(
"99 s2 42 text 1 2 3 s2 41 texty 1 3 2",
int_ >> *s2_rule_a,
ws,
result));
auto i_ = get(result, llong<0>{});
EXPECT_EQ(i_, 99);
auto structs_ = get(result, llong<1>{});
EXPECT_EQ(get(structs_[0], llong<0>{}), 42);
EXPECT_EQ(get(structs_[0], llong<1>{}), "text");
EXPECT_EQ(get(structs_[0], llong<2>{}), std::vector<int>({1, 2, 3}));
EXPECT_EQ(get(structs_[1], llong<0>{}), 41);
EXPECT_EQ(get(structs_[1], llong<1>{}), "texty");
EXPECT_EQ(get(structs_[1], llong<2>{}), std::vector<int>({1, 3, 2}));
}
{
tuple<int, std::vector<s2>> result;
EXPECT_TRUE(parse(
"99 s2 42 text 1 2 3 s2 41 texty 1 3 2",
int_ >> *s2_rule_b,
ws,
result));
auto i_ = get(result, llong<0>{});
EXPECT_EQ(i_, 99);
auto structs_ = get(result, llong<1>{});
EXPECT_EQ(get(structs_[0], llong<0>{}), 42);
EXPECT_EQ(get(structs_[0], llong<1>{}), "text");
EXPECT_EQ(get(structs_[0], llong<2>{}), std::vector<int>({1, 2, 3}));
EXPECT_EQ(get(structs_[1], llong<0>{}), 41);
EXPECT_EQ(get(structs_[1], llong<1>{}), "texty");
EXPECT_EQ(get(structs_[1], llong<2>{}), std::vector<int>({1, 3, 2}));
}
}
struct callbacks_t
{
void operator()(s0_rule_tag, s0 s) const { s0s.push_back(std::move(s)); }
void operator()(s1_rule_a_tag, s1 s) const { s1s.push_back(std::move(s)); }
void operator()(s1_rule_b_tag, s1 s) const { s1s.push_back(std::move(s)); }
void operator()(s2_rule_a_tag, s2 s) const { s2s.push_back(std::move(s)); }
void operator()(s2_rule_b_tag, s2 s) const { s2s.push_back(std::move(s)); }
mutable std::vector<s0> s0s;
mutable std::vector<s1> s1s;
mutable std::vector<s2> s2s;
};
TEST(struct_tuple, seq_parser_struct_cb_rule)
{
{
callbacks_t callbacks;
EXPECT_TRUE(callback_parse("s0 42 text 1 2 3", s0_rule, ws, callbacks));
EXPECT_EQ(callbacks.s0s.size(), 1u);
s0 const & struct_ = callbacks.s0s[0];
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}), "text");
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
{
callbacks_t callbacks;
EXPECT_TRUE(callback_parse("s1 42 text 1 2 3", s1_rule_a, ws, callbacks));
EXPECT_EQ(callbacks.s1s.size(), 1u);
s1 const & struct_ = callbacks.s1s[0];
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}).index(), 0u);
EXPECT_EQ(std::get<0>(get(struct_, llong<1>{})), "text");
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
{
callbacks_t callbacks;
EXPECT_TRUE(callback_parse("s1 42 13.0 1 2 3", s1_rule_b, ws, callbacks));
EXPECT_EQ(callbacks.s1s.size(), 1u);
s1 const & struct_ = callbacks.s1s[0];
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}).index(), 1u);
EXPECT_EQ(std::get<1>(get(struct_, llong<1>{})), 13.0);
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
{
callbacks_t callbacks;
EXPECT_TRUE(callback_parse("s2 42 text 1 2 3", s2_rule_a, ws, callbacks));
EXPECT_EQ(callbacks.s2s.size(), 1u);
s2 const & struct_ = callbacks.s2s[0];
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}), "text");
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
{
callbacks_t callbacks;
EXPECT_TRUE(callback_parse("s2 42 text 1 2 3", s2_rule_b, ws, callbacks));
EXPECT_EQ(callbacks.s2s.size(), 1u);
s2 const & struct_ = callbacks.s2s[0];
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}), "text");
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
// Use the rule as part of a larger parse.
{
callbacks_t callbacks;
EXPECT_TRUE(callback_parse(
"99 s0 42 text 1 2 3", int_ >> s0_rule, ws, callbacks));
EXPECT_EQ(callbacks.s0s.size(), 1u);
s0 const & struct_ = callbacks.s0s[0];
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}), "text");
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
{
callbacks_t callbacks;
EXPECT_TRUE(callback_parse(
"99 s1 42 text 1 2 3", int_ >> s1_rule_a, ws, callbacks));
EXPECT_EQ(callbacks.s1s.size(), 1u);
s1 const & struct_ = callbacks.s1s[0];
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}).index(), 0u);
EXPECT_EQ(std::get<0>(get(struct_, llong<1>{})), "text");
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
{
callbacks_t callbacks;
EXPECT_TRUE(callback_parse(
"99 s1 42 13.0 1 2 3", int_ >> s1_rule_b, ws, callbacks));
EXPECT_EQ(callbacks.s1s.size(), 1u);
s1 const & struct_ = callbacks.s1s[0];
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}).index(), 1u);
EXPECT_EQ(std::get<1>(get(struct_, llong<1>{})), 13.0);
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
{
callbacks_t callbacks;
EXPECT_TRUE(callback_parse(
"99 s2 42 text 1 2 3", int_ >> s2_rule_a, ws, callbacks));
EXPECT_EQ(callbacks.s2s.size(), 1u);
s2 const & struct_ = callbacks.s2s[0];
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}), "text");
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
{
callbacks_t callbacks;
EXPECT_TRUE(callback_parse(
"99 s2 42 text 1 2 3", int_ >> s2_rule_b, ws, callbacks));
EXPECT_EQ(callbacks.s2s.size(), 1u);
s2 const & struct_ = callbacks.s2s[0];
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}), "text");
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
}
TEST(struct_tuple, parse_into_struct)
{
// tuples
{
s0_tuple tuple_;
EXPECT_TRUE(parse("s0 42 text 1 2 3", s0_parser, ws, tuple_));
EXPECT_EQ(get(tuple_, llong<0>{}), 42);
EXPECT_EQ(get(tuple_, llong<1>{}), "text");
EXPECT_EQ(get(tuple_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
{
s1_tuple tuple_;
EXPECT_TRUE(parse("s1 42 text 1 2 3", s1_parser_a, ws, tuple_));
EXPECT_EQ(get(tuple_, llong<0>{}), 42);
EXPECT_EQ(get(tuple_, llong<1>{}).index(), 0u);
EXPECT_EQ(std::get<0>(get(tuple_, llong<1>{})), "text");
EXPECT_EQ(get(tuple_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
{
s1_tuple tuple_;
EXPECT_TRUE(parse("s1 42 13.0 1 2 3", s1_parser_b, ws, tuple_));
EXPECT_EQ(get(tuple_, llong<0>{}), 42);
EXPECT_EQ(get(tuple_, llong<1>{}).index(), 1u);
EXPECT_EQ(std::get<1>(get(tuple_, llong<1>{})), 13.0);
EXPECT_EQ(get(tuple_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
{
s2_tuple tuple_;
EXPECT_TRUE(parse("s2 42 text 1 2 3", s2_parser_a, ws, tuple_));
EXPECT_EQ(get(tuple_, llong<0>{}), 42);
EXPECT_EQ(get(tuple_, llong<1>{}), "text");
EXPECT_EQ(get(tuple_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
{
s2_tuple tuple_;
EXPECT_TRUE(parse("s2 42 text 1 2 3", s2_parser_b, ws, tuple_));
EXPECT_EQ(get(tuple_, llong<0>{}), 42);
EXPECT_EQ(get(tuple_, llong<1>{}), "text");
EXPECT_EQ(get(tuple_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
// structs
{
s0 struct_;
EXPECT_TRUE(parse("s0 42 text 1 2 3", s0_parser, ws, struct_));
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}), "text");
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
{
s0_like struct_;
EXPECT_TRUE(parse("s0 42 text 1 2 3", s0_parser, ws, struct_));
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}), "text");
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
{
s1 struct_;
EXPECT_TRUE(parse("s1 42 text 1 2 3", s1_parser_a, ws, struct_));
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}).index(), 0u);
EXPECT_EQ(std::get<0>(get(struct_, llong<1>{})), "text");
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
{
s1 struct_;
EXPECT_TRUE(parse("s1 42 13.0 1 2 3", s1_parser_b, ws, struct_));
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}).index(), 1u);
EXPECT_EQ(std::get<1>(get(struct_, llong<1>{})), 13.0);
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
{
s2 struct_;
EXPECT_TRUE(parse("s2 42 text 1 2 3", s2_parser_a, ws, struct_));
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}), "text");
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
{
s2 struct_;
EXPECT_TRUE(parse("s2 42 text 1 2 3", s2_parser_b, ws, struct_));
EXPECT_EQ(get(struct_, llong<0>{}), 42);
EXPECT_EQ(get(struct_, llong<1>{}), "text");
EXPECT_EQ(get(struct_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
}
TEST(struct_tuple, repeated_parse_into_struct)
{
// tuples
{
std::vector<s0_tuple> tuples_;
EXPECT_TRUE(parse(
"s0 42 text 1 2 3 s0 41 texty 1 3 2", *s0_parser, ws, tuples_));
EXPECT_EQ(get(tuples_[0], llong<0>{}), 42);
EXPECT_EQ(get(tuples_[0], llong<1>{}), "text");
EXPECT_EQ(get(tuples_[0], llong<2>{}), std::vector<int>({1, 2, 3}));
EXPECT_EQ(get(tuples_[1], llong<0>{}), 41);
EXPECT_EQ(get(tuples_[1], llong<1>{}), "texty");
EXPECT_EQ(get(tuples_[1], llong<2>{}), std::vector<int>({1, 3, 2}));
}
{
std::vector<s1_tuple> tuples_;
EXPECT_TRUE(parse(
"s1 42 text 1 2 3 s1 41 texty 1 3 2", *s1_parser_a, ws, tuples_));
EXPECT_EQ(get(tuples_[0], llong<0>{}), 42);
EXPECT_EQ(get(tuples_[0], llong<1>{}).index(), 0u);
EXPECT_EQ(std::get<0>(get(tuples_[0], llong<1>{})), "text");
EXPECT_EQ(get(tuples_[0], llong<2>{}), std::vector<int>({1, 2, 3}));
EXPECT_EQ(get(tuples_[1], llong<0>{}), 41);
EXPECT_EQ(get(tuples_[1], llong<1>{}).index(), 0u);
EXPECT_EQ(std::get<0>(get(tuples_[1], llong<1>{})), "texty");
EXPECT_EQ(get(tuples_[1], llong<2>{}), std::vector<int>({1, 3, 2}));
}
{
std::vector<s1_tuple> tuples_;
EXPECT_TRUE(parse(
"s1 42 13.0 1 2 3 s1 41 12.0 1 3 2", *s1_parser_b, ws, tuples_));
EXPECT_EQ(get(tuples_[0], llong<0>{}), 42);
EXPECT_EQ(get(tuples_[0], llong<1>{}).index(), 1u);
EXPECT_EQ(std::get<1>(get(tuples_[0], llong<1>{})), 13.0);
EXPECT_EQ(get(tuples_[0], llong<2>{}), std::vector<int>({1, 2, 3}));
EXPECT_EQ(get(tuples_[1], llong<0>{}), 41);
EXPECT_EQ(get(tuples_[1], llong<1>{}).index(), 1u);
EXPECT_EQ(std::get<1>(get(tuples_[1], llong<1>{})), 12.0);
EXPECT_EQ(get(tuples_[1], llong<2>{}), std::vector<int>({1, 3, 2}));
}
{
std::vector<s2_tuple> tuples_;
EXPECT_TRUE(parse(
"s2 42 text 1 2 3 s2 41 texty 1 3 2", *s2_parser_a, ws, tuples_));
EXPECT_EQ(get(tuples_[0], llong<0>{}), 42);
EXPECT_EQ(get(tuples_[0], llong<1>{}), "text");
EXPECT_EQ(get(tuples_[0], llong<2>{}), std::vector<int>({1, 2, 3}));
EXPECT_EQ(get(tuples_[1], llong<0>{}), 41);
EXPECT_EQ(get(tuples_[1], llong<1>{}), "texty");
EXPECT_EQ(get(tuples_[1], llong<2>{}), std::vector<int>({1, 3, 2}));
}
{
std::vector<s2_tuple> tuples_;
EXPECT_TRUE(parse(
"s2 42 text 1 2 3 s2 41 texty 1 3 2", *s2_parser_b, ws, tuples_));
EXPECT_EQ(get(tuples_[0], llong<0>{}), 42);
EXPECT_EQ(get(tuples_[0], llong<1>{}), "text");
EXPECT_EQ(get(tuples_[0], llong<2>{}), std::vector<int>({1, 2, 3}));
EXPECT_EQ(get(tuples_[1], llong<0>{}), 41);
EXPECT_EQ(get(tuples_[1], llong<1>{}), "texty");
EXPECT_EQ(get(tuples_[1], llong<2>{}), std::vector<int>({1, 3, 2}));
}
// structs
{
std::vector<s0> structs_;
EXPECT_TRUE(parse(
"s0 42 text 1 2 3 s0 41 texty 1 3 2", *s0_parser, ws, structs_));
EXPECT_EQ(get(structs_[0], llong<0>{}), 42);
EXPECT_EQ(get(structs_[0], llong<1>{}), "text");
EXPECT_EQ(get(structs_[0], llong<2>{}), std::vector<int>({1, 2, 3}));
EXPECT_EQ(get(structs_[1], llong<0>{}), 41);
EXPECT_EQ(get(structs_[1], llong<1>{}), "texty");
EXPECT_EQ(get(structs_[1], llong<2>{}), std::vector<int>({1, 3, 2}));
}
{
std::vector<s0_like> structs_;
EXPECT_TRUE(parse(
"s0 42 text 1 2 3 s0 41 texty 1 3 2", *s0_parser, ws, structs_));
EXPECT_EQ(get(structs_[0], llong<0>{}), 42);
EXPECT_EQ(get(structs_[0], llong<1>{}), "text");
EXPECT_EQ(get(structs_[0], llong<2>{}), std::vector<int>({1, 2, 3}));
EXPECT_EQ(get(structs_[1], llong<0>{}), 41);
EXPECT_EQ(get(structs_[1], llong<1>{}), "texty");
EXPECT_EQ(get(structs_[1], llong<2>{}), std::vector<int>({1, 3, 2}));
}
{
std::vector<s1> structs_;
EXPECT_TRUE(parse(
"s1 42 text 1 2 3 s1 41 texty 1 3 2", *s1_parser_a, ws, structs_));
EXPECT_EQ(get(structs_[0], llong<0>{}), 42);
EXPECT_EQ(get(structs_[0], llong<1>{}).index(), 0u);
EXPECT_EQ(std::get<0>(get(structs_[0], llong<1>{})), "text");
EXPECT_EQ(get(structs_[0], llong<2>{}), std::vector<int>({1, 2, 3}));
EXPECT_EQ(get(structs_[1], llong<0>{}), 41);
EXPECT_EQ(get(structs_[1], llong<1>{}).index(), 0u);
EXPECT_EQ(std::get<0>(get(structs_[1], llong<1>{})), "texty");
EXPECT_EQ(get(structs_[1], llong<2>{}), std::vector<int>({1, 3, 2}));
}
{
std::vector<s1> structs_;
EXPECT_TRUE(parse(
"s1 42 13.0 1 2 3 s1 41 12.0 1 3 2", *s1_parser_b, ws, structs_));
EXPECT_EQ(get(structs_[0], llong<0>{}), 42);
EXPECT_EQ(get(structs_[0], llong<1>{}).index(), 1u);
EXPECT_EQ(std::get<1>(get(structs_[0], llong<1>{})), 13.0);
EXPECT_EQ(get(structs_[0], llong<2>{}), std::vector<int>({1, 2, 3}));
EXPECT_EQ(get(structs_[1], llong<0>{}), 41);
EXPECT_EQ(get(structs_[1], llong<1>{}).index(), 1u);
EXPECT_EQ(std::get<1>(get(structs_[1], llong<1>{})), 12.0);
EXPECT_EQ(get(structs_[1], llong<2>{}), std::vector<int>({1, 3, 2}));
}
{
std::vector<s2> structs_;
EXPECT_TRUE(parse(
"s2 42 text 1 2 3 s2 41 texty 1 3 2", *s2_parser_a, ws, structs_));
EXPECT_EQ(get(structs_[0], llong<0>{}), 42);
EXPECT_EQ(get(structs_[0], llong<1>{}), "text");
EXPECT_EQ(get(structs_[0], llong<2>{}), std::vector<int>({1, 2, 3}));
EXPECT_EQ(get(structs_[1], llong<0>{}), 41);
EXPECT_EQ(get(structs_[1], llong<1>{}), "texty");
EXPECT_EQ(get(structs_[1], llong<2>{}), std::vector<int>({1, 3, 2}));
}
{
std::vector<s2> structs_;
EXPECT_TRUE(parse(
"s2 42 text 1 2 3 s2 41 texty 1 3 2", *s2_parser_b, ws, structs_));
EXPECT_EQ(get(structs_[0], llong<0>{}), 42);
EXPECT_EQ(get(structs_[0], llong<1>{}), "text");
EXPECT_EQ(get(structs_[0], llong<2>{}), std::vector<int>({1, 2, 3}));
EXPECT_EQ(get(structs_[1], llong<0>{}), 41);
EXPECT_EQ(get(structs_[1], llong<1>{}), "texty");
EXPECT_EQ(get(structs_[1], llong<2>{}), std::vector<int>({1, 3, 2}));
}
}
TEST(struct_tuple, parse_into_tuple)
{
{
s0_tuple tuple_;
EXPECT_TRUE(parse("s0 42 text 1 2 3", s0_rule, ws, tuple_));
EXPECT_EQ(get(tuple_, llong<0>{}), 42);
EXPECT_EQ(get(tuple_, llong<1>{}), "text");
EXPECT_EQ(get(tuple_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
{
s1_tuple tuple_;
EXPECT_TRUE(parse("s1 42 text 1 2 3", s1_rule_a, ws, tuple_));
EXPECT_EQ(get(tuple_, llong<0>{}), 42);
EXPECT_EQ(get(tuple_, llong<1>{}).index(), 0u);
EXPECT_EQ(std::get<0>(get(tuple_, llong<1>{})), "text");
EXPECT_EQ(get(tuple_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
{
s1_tuple tuple_;
EXPECT_TRUE(parse("s1 42 13.0 1 2 3", s1_rule_b, ws, tuple_));
EXPECT_EQ(get(tuple_, llong<0>{}), 42);
EXPECT_EQ(get(tuple_, llong<1>{}).index(), 1u);
EXPECT_EQ(std::get<1>(get(tuple_, llong<1>{})), 13.0);
EXPECT_EQ(get(tuple_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
{
s2_tuple tuple_;
EXPECT_TRUE(parse("s2 42 text 1 2 3", s2_rule_a, ws, tuple_));
EXPECT_EQ(get(tuple_, llong<0>{}), 42);
EXPECT_EQ(get(tuple_, llong<1>{}), "text");
EXPECT_EQ(get(tuple_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
{
s2_tuple tuple_;
EXPECT_TRUE(parse("s2 42 text 1 2 3", s2_rule_b, ws, tuple_));
EXPECT_EQ(get(tuple_, llong<0>{}), 42);
EXPECT_EQ(get(tuple_, llong<1>{}), "text");
EXPECT_EQ(get(tuple_, llong<2>{}), std::vector<int>({1, 2, 3}));
}
}
TEST(struct_tuple, repeated_parse_into_tuple)
{
{
std::vector<s0_tuple> tuples_;
EXPECT_TRUE(
parse("s0 42 text 1 2 3 s0 41 texty 1 3 2", *s0_rule, ws, tuples_));
EXPECT_EQ(get(tuples_[0], llong<0>{}), 42);
EXPECT_EQ(get(tuples_[0], llong<1>{}), "text");
EXPECT_EQ(get(tuples_[0], llong<2>{}), std::vector<int>({1, 2, 3}));
EXPECT_EQ(get(tuples_[1], llong<0>{}), 41);
EXPECT_EQ(get(tuples_[1], llong<1>{}), "texty");
EXPECT_EQ(get(tuples_[1], llong<2>{}), std::vector<int>({1, 3, 2}));
}
{
std::vector<s1_tuple> tuples_;
EXPECT_TRUE(parse(
"s1 42 text 1 2 3 s1 41 texty 1 3 2", *s1_rule_a, ws, tuples_));
EXPECT_EQ(get(tuples_[0], llong<0>{}), 42);
EXPECT_EQ(get(tuples_[0], llong<1>{}).index(), 0u);
EXPECT_EQ(std::get<0>(get(tuples_[0], llong<1>{})), "text");
EXPECT_EQ(get(tuples_[0], llong<2>{}), std::vector<int>({1, 2, 3}));
EXPECT_EQ(get(tuples_[1], llong<0>{}), 41);
EXPECT_EQ(get(tuples_[1], llong<1>{}).index(), 0u);
EXPECT_EQ(std::get<0>(get(tuples_[1], llong<1>{})), "texty");
EXPECT_EQ(get(tuples_[1], llong<2>{}), std::vector<int>({1, 3, 2}));
}
{
std::vector<s1_tuple> tuples_;
EXPECT_TRUE(parse(
"s1 42 13.0 1 2 3 s1 41 12.0 1 3 2", *s1_rule_b, ws, tuples_));
EXPECT_EQ(get(tuples_[0], llong<0>{}), 42);
EXPECT_EQ(get(tuples_[0], llong<1>{}).index(), 1u);
EXPECT_EQ(std::get<1>(get(tuples_[0], llong<1>{})), 13.0);
EXPECT_EQ(get(tuples_[0], llong<2>{}), std::vector<int>({1, 2, 3}));
EXPECT_EQ(get(tuples_[1], llong<0>{}), 41);
EXPECT_EQ(get(tuples_[1], llong<1>{}).index(), 1u);
EXPECT_EQ(std::get<1>(get(tuples_[1], llong<1>{})), 12.0);
EXPECT_EQ(get(tuples_[1], llong<2>{}), std::vector<int>({1, 3, 2}));
}
{
std::vector<s2_tuple> tuples_;
EXPECT_TRUE(parse(
"s2 42 text 1 2 3 s2 41 texty 1 3 2", *s2_rule_a, ws, tuples_));
EXPECT_EQ(get(tuples_[0], llong<0>{}), 42);
EXPECT_EQ(get(tuples_[0], llong<1>{}), "text");
EXPECT_EQ(get(tuples_[0], llong<2>{}), std::vector<int>({1, 2, 3}));
EXPECT_EQ(get(tuples_[1], llong<0>{}), 41);
EXPECT_EQ(get(tuples_[1], llong<1>{}), "texty");
EXPECT_EQ(get(tuples_[1], llong<2>{}), std::vector<int>({1, 3, 2}));
}
{
std::vector<s2_tuple> tuples_;
EXPECT_TRUE(parse(
"s2 42 text 1 2 3 s2 41 texty 1 3 2", *s2_rule_b, ws, tuples_));
EXPECT_EQ(get(tuples_[0], llong<0>{}), 42);
EXPECT_EQ(get(tuples_[0], llong<1>{}), "text");
EXPECT_EQ(get(tuples_[0], llong<2>{}), std::vector<int>({1, 2, 3}));
EXPECT_EQ(get(tuples_[1], llong<0>{}), 41);
EXPECT_EQ(get(tuples_[1], llong<1>{}), "texty");
EXPECT_EQ(get(tuples_[1], llong<2>{}), std::vector<int>({1, 3, 2}));
}
}