#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/support_utree.hpp>
#include <boost/phoenix/core.hpp>
#include <boost/phoenix/operator.hpp>
#include <boost/fusion/include/std_pair.hpp>
#include <boost/proto/deep_copy.hpp>
#include <iostream>
#include <string>
#include <boost/spirit/include/karma.hpp>
#include <iostream>
#include <string>
typedef std::back_insert_iterator<std::string> output_iterator_type;
template <typename G>
void test_generator(char const* expected, G const& g)
{
std::string s;
std::back_insert_iterator<std::string> out(s);
if (boost::spirit::karma::generate(out, g) && s == expected)
std::cout << "ok" << std::endl;
else
std::cout << "fail" << std::endl;
}
template <typename G, typename T>
void test_generator_attr(char const* expected, G const& g, T const& attr)
{
std::string s;
std::back_insert_iterator<std::string> out(s);
if (boost::spirit::karma::generate(out, g, attr) && s == expected)
std::cout << "ok" << std::endl;
else
std::cout << "fail" << std::endl;
}
template <typename G, typename T1, typename T2>
void test_generator_attr(char const* expected, G const& g, T1 const& attr1,
T2 const& attr2)
{
std::string s;
std::back_insert_iterator<std::string> out(s);
if (boost::spirit::karma::generate(out, g, attr1, attr2) && s == expected)
std::cout << "ok" << std::endl;
else
std::cout << "fail" << std::endl;
}
template <typename G, typename Delimiter, typename T>
void test_generator_attr_delim(char const* expected, G const& g, Delimiter const& d, T const& attr)
{
std::string s;
std::back_insert_iterator<std::string> out(s);
if (boost::spirit::karma::generate_delimited(out, g, d, attr) && s == expected)
std::cout << "ok" << std::endl;
else
std::cout << "fail" << std::endl;
}
template <typename G>
void test_binary_generator(char const* expected, std::size_t size, G const& g)
{
std::string s;
std::back_insert_iterator<std::string> out(s);
if (boost::spirit::karma::generate(out, g) && !std::memcmp(s.c_str(), expected, size))
std::cout << "ok" << std::endl;
else
std::cout << "fail" << std::endl;
}
template <typename G, typename T>
void test_binary_generator_attr(char const* expected, std::size_t size, G const& g, T const& attr)
{
std::string s;
std::back_insert_iterator<std::string> out(s);
if (boost::spirit::karma::generate(out, g, attr) && !std::memcmp(s.c_str(), expected, size))
std::cout << "ok" << std::endl;
else
std::cout << "fail" << std::endl;
}
struct complex
{
complex (double a, double b)
: a(a), b(b)
{}
double a;
double b;
};
std::ostream&
operator<< (std::ostream& os, complex const& z)
{
os << "{" << z.a << "," << z.b << "}";
return os;
}
BOOST_FUSION_ADAPT_STRUCT(
complex,
(double, a)
(double, b)
)
namespace boost { namespace spirit { namespace traits
{
template <>
struct create_generator<complex>
{
typedef proto::result_of::deep_copy<
BOOST_TYPEOF('{' << karma::double_ << ',' << karma::double_ << '}')
>::type type;
static type call()
{
return proto::deep_copy(
'{' << karma::double_ << ',' << karma::double_ << '}');
}
};
}}}
struct int_data
{
int i;
};
namespace boost { namespace spirit { namespace traits
{
template <>
struct transform_attribute<int_data const, int, karma::domain>
{
typedef int type;
static int pre(int_data const& d) { return d.i; }
};
}}}
namespace client
{
using boost::spirit::karma::grammar;
using boost::spirit::karma::rule;
using boost::spirit::ascii::space_type;
struct num_list : grammar<output_iterator_type, space_type, std::vector<int>()>
{
num_list() : base_type(start)
{
using boost::spirit::int_;
num = int_;
start = num << *(',' << num);
}
rule<output_iterator_type, space_type, std::vector<int>()> start;
rule<output_iterator_type, space_type, int()> num;
};
}
int main()
{
{
using boost::spirit::karma::double_;
test_generator_attr("1.0,2.0", double_ << ',' << double_, std::make_pair(1.0, 2.0));
}
{
using boost::spirit::karma::double_;
using boost::spirit::karma::ascii::string;
boost::variant<std::string, double> v1(1.0);
test_generator_attr("1.0", string | double_, v1);
test_generator_attr("2.0", string | double_, 2.0);
boost::variant<std::string, double> v2("example");
test_generator_attr("example", string | double_, v2);
test_generator_attr("example", string | double_, "example");
}
{
using boost::spirit::karma::double_;
using boost::spirit::karma::space;
std::vector<double> v;
v.push_back(1.0);
v.push_back(2.0);
v.push_back(3.0);
test_generator_attr_delim("1.0 2.0 3.0 ", *double_, space, v);
}
{
using boost::spirit::karma::double_;
using boost::spirit::karma::space;
std::vector<double> v1;
v1.push_back(1.0);
v1.push_back(2.0);
v1.push_back(3.0);
test_generator_attr_delim("1.0 2.0 3.0 ", +double_, space, v1);
std::vector<double> v2; test_generator_attr("empty", +double_ | "empty", v2);
}
{
using boost::spirit::karma::double_;
std::vector<double> v1;
v1.push_back(1.0);
test_generator_attr("1.0", double_ % ',', v1);
v1.push_back(2.0);
test_generator_attr("1.0,2.0", double_ % ',', v1);
}
{
using boost::spirit::karma::double_;
boost::optional<double> val(1.0);
test_generator_attr("1.0", -double_, val);
test_generator_attr("2.0", -double_, 2.0);
}
{
using boost::spirit::karma::double_;
boost::optional<double> val; test_generator_attr("", -double_, val);
}
{
using boost::spirit::karma::double_;
using boost::spirit::karma::ascii::char_;
using boost::spirit::karma::ascii::string;
using boost::phoenix::ref;
test_generator_attr("b", &char_('a') << 'b' | 'c', 'a');
test_generator_attr("c", &char_('a') << 'b' | 'c', 'x');
test_generator_attr("abc", &string("123") << "abc" | "def", "123");
test_generator_attr("def", &string("123") << "abc" | "def", "456");
}
{
using boost::spirit::karma::double_;
using boost::spirit::karma::ascii::char_;
using boost::spirit::karma::ascii::string;
using boost::phoenix::ref;
test_generator_attr("c", !char_('a') << 'b' | 'c', 'a');
test_generator_attr("b", !char_('a') << 'b' | 'c', 'x');
test_generator_attr("def", !string("123") << "abc" | "def", "123");
test_generator_attr("abc", !string("123") << "abc" | "def", "456");
}
{
using boost::spirit::karma::double_;
using boost::spirit::karma::left_align;
using boost::spirit::karma::center;
using boost::spirit::karma::right_align;
std::pair<double, double> p (1.0, 2.0);
test_generator_attr("1.0 |2.0", left_align(8)[double_] << '|' << double_, p);
test_generator_attr(" 1.0 |2.0", center(8)[double_] << '|' << double_, p);
test_generator_attr(" 1.0|2.0", right_align(8)[double_] << '|' << double_, p);
}
{
using boost::spirit::karma::double_;
using boost::spirit::karma::repeat;
std::vector<double> v;
v.push_back(1.0);
v.push_back(2.0);
v.push_back(3.0);
test_generator_attr("[1.0][2.0][3.0]", repeat['[' << double_ << ']'], v);
test_generator_attr("[1.0][2.0]", repeat(2)['[' << double_ << ']'], v);
test_generator_attr("", repeat(4)['[' << double_ << ']'], v);
}
{
using boost::spirit::karma::double_;
using boost::spirit::karma::delimit;
using boost::spirit::karma::verbatim;
test_generator_attr("[ 2.0 , 4.3 ] ",
delimit['[' << double_ << ',' << double_ << ']'], 2.0, 4.3);
test_generator_attr("[*2.0*,*4.3*]*",
delimit('*')['[' << double_ << ',' << double_ << ']'], 2.0, 4.3);
test_generator_attr("[2.0, 4.3 ] ",
delimit[verbatim['[' << double_ << ','] << double_ << ']'], 2.0, 4.3);
}
{
using boost::spirit::karma::double_;
using boost::spirit::ascii::upper;
using boost::spirit::ascii::lower;
test_generator_attr("abc:2.0e-06", lower["ABC:" << double_], 2e-6);
test_generator_attr("ABC:2.0E-06", upper["abc:" << double_], 2e-6);
}
{
using boost::spirit::karma::double_;
using boost::spirit::karma::maxwidth;
using boost::spirit::karma::left_align;
using boost::spirit::karma::right_align;
test_generator("01234", maxwidth(5)["0123456789"]);
test_generator(" 012", maxwidth(5)[right_align(12)["0123456789"]]);
test_generator("0123 ", maxwidth(8)[left_align(8)["0123"]]);
}
{
using boost::spirit::karma::double_;
using boost::spirit::karma::buffer;
std::vector<double> v; test_generator_attr("", -buffer['[' << +double_ << ']'], v);
v.push_back(1.0); v.push_back(2.0);
test_generator_attr("[1.02.0]", buffer['[' << +double_ << ']'], v);
}
{
using boost::spirit::karma::double_;
using boost::spirit::karma::omit;
std::pair<double, double> p (1.0, 2.0);
test_generator_attr("2.0", omit[double_] << double_, p);
}
{
using boost::spirit::karma::double_;
using boost::spirit::karma::duplicate;
using boost::spirit::karma::space;
test_generator_attr("2.02.0", duplicate[double_ << double_], 2.0);
test_generator_attr_delim("2.0 2.0 ", duplicate[double_ << double_], space, 2.0);
}
{
using boost::spirit::karma::double_;
using boost::spirit::karma::columns;
using boost::spirit::karma::space;
std::vector<double> v;
v.push_back(1.0);
v.push_back(2.0);
v.push_back(3.0);
test_generator_attr("1.0\n2.0\n3.0\n", columns(1)[*double_], v);
test_generator_attr_delim("1.0 2.0 \n3.0 \n", columns(2)[*double_], space, v);
}
{
using boost::spirit::karma::bool_;
using boost::spirit::karma::lit;
test_generator("true", lit(true));
test_generator("false", bool_(false));
test_generator_attr("true", bool_(true), true);
test_generator_attr("", bool_(true), false); test_generator_attr("false", bool_, false);
}
{
using boost::spirit::karma::int_;
using boost::spirit::karma::lit;
test_generator("-2", lit(-2));
test_generator("-2", int_(-2));
test_generator_attr("-2", int_(-2), -2);
test_generator_attr("", int_(-2), 3); test_generator_attr("-2", int_, -2);
}
{
using boost::spirit::karma::uint_;
using boost::spirit::karma::lit;
test_generator("2", lit(2U));
test_generator("2", uint_(2));
test_generator_attr("2", uint_(2), 2);
test_generator_attr("", uint_(2), 3); test_generator_attr("2", uint_, 2);
}
{
using boost::spirit::karma::double_;
using boost::spirit::karma::lit;
test_generator("2.0", lit(2.0));
test_generator("2.0", double_(2));
test_generator_attr("2.0", double_(2.0), 2.0);
test_generator_attr("", double_(2.0), 3.0); test_generator_attr("-2.0", double_, -2.0);
test_generator_attr("1.234e05", double_, 1234.0e2);
test_generator_attr("1.234e-06", double_, 0.000001234);
}
{
using boost::spirit::karma::lit;
using boost::spirit::ascii::char_;
test_generator("A", 'A');
test_generator("A", lit('A'));
test_generator_attr("a", char_, 'a');
test_generator("A", char_('A'));
test_generator_attr("A", char_('A'), 'A');
test_generator_attr("", char_('A'), 'B');
test_generator_attr("A", char_('A', 'Z'), 'A');
test_generator_attr("", char_('A', 'Z'), 'a');
test_generator_attr("k", char_("a-z0-9"), 'k');
test_generator_attr("", char_("a-z0-9"), 'A'); }
{
using boost::spirit::karma::alpha;
using boost::spirit::karma::upper;
test_generator_attr("a", alpha, 'a');
test_generator_attr("A", alpha, 'A');
test_generator_attr("", alpha, '1'); test_generator_attr("A", upper[alpha], 'A');
test_generator_attr("", upper[alpha], 'a'); }
{
using boost::spirit::karma::lit;
using boost::spirit::ascii::string;
test_generator("abc", "abc");
test_generator("abc", lit("abc"));
test_generator("abc", lit(std::string("abc")));
test_generator_attr("abc", string, "abc");
test_generator("abc", string("abc"));
test_generator("abc", string(std::string("abc")));
test_generator_attr("abc", string("abc"), "abc");
test_generator_attr("", string("abc"), "cba"); }
{
using boost::spirit::karma::eol;
test_generator("\n", eol);
test_generator("abc\n", "abc" << eol);
}
{
using boost::spirit::karma::int_;
int_data d = { 1 };
test_generator_attr("1", boost::spirit::karma::attr_cast(int_), d);
}
{
using boost::spirit::karma::eps;
using boost::phoenix::val;
test_generator("abc", eps[std::cout << val("starting eps example")] << "abc");
test_generator("abc", eps(true) << "abc");
test_generator("", eps(false) << "abc"); }
{
namespace karma = boost::spirit::karma;
using boost::spirit::karma::_1;
using boost::spirit::ascii::string;
using boost::phoenix::val;
test_generator_attr("abc", karma::lazy(val(string)), "abc");
test_generator("abc", karma::lazy(val(string))[_1 = "abc"]);
}
{
using boost::spirit::karma::stream;
test_generator_attr("abc", stream, "abc");
test_generator("abc", stream("abc"));
test_generator_attr("{1.2,2.4}", stream, complex(1.2, 2.4));
test_generator("{1.2,2.4}", stream(complex(1.2, 2.4)));
}
{
using boost::spirit::karma::auto_;
test_generator_attr("abc", auto_, "abc");
test_generator("abc", auto_("abc"));
test_generator_attr("{1.2,2.4}", auto_, complex(1.2, 2.4));
test_generator("{1.2,2.4}", auto_(complex(1.2, 2.4)));
}
{
using boost::spirit::karma::byte_;
using boost::spirit::karma::word;
using boost::spirit::karma::dword;
using boost::spirit::karma::qword;
test_binary_generator("\x01", 1, byte_(0x01));
test_binary_generator("\x01\x02", 2, word(0x0201));
test_binary_generator("\x01\x02\x03\x04", 4, dword(0x04030201));
test_binary_generator("\x01\x02\x03\x04\x05\x06\x07\x08", 8, qword(0x0807060504030201LL));
test_binary_generator_attr("\x01", 1, byte_, 0x01);
test_binary_generator_attr("\x01\x02", 2, word, 0x0201);
test_binary_generator_attr("\x01\x02\x03\x04", 4, dword, 0x04030201);
test_binary_generator_attr("\x01\x02\x03\x04\x05\x06\x07\x08", 8, qword, 0x0807060504030201LL);
test_binary_generator("\x01", 1, byte_(0x01));
test_binary_generator("\x02\x01", 2, word(0x0201));
test_binary_generator("\x04\x03\x02\x01", 4, dword(0x04030201));
test_binary_generator("\x08\x07\x06\x05\x04\x03\x02\x01", 8, qword(0x0807060504030201LL));
test_binary_generator_attr("\x01", 1, byte_, 0x01);
test_binary_generator_attr("\x02\x01", 2, word, 0x0201);
test_binary_generator_attr("\x04\x03\x02\x01", 4, dword, 0x04030201);
test_binary_generator_attr("\x08\x07\x06\x05\x04\x03\x02\x01", 8, qword, 0x0807060504030201LL);
}
{
using boost::spirit::karma::little_word;
using boost::spirit::karma::little_dword;
using boost::spirit::karma::little_qword;
test_binary_generator("\x01\x02", 2, little_word(0x0201));
test_binary_generator("\x01\x02\x03\x04", 4, little_dword(0x04030201));
test_binary_generator("\x01\x02\x03\x04\x05\x06\x07\x08", 8, little_qword(0x0807060504030201LL));
test_binary_generator_attr("\x01\x02", 2, little_word, 0x0201);
test_binary_generator_attr("\x01\x02\x03\x04", 4, little_dword, 0x04030201);
test_binary_generator_attr("\x01\x02\x03\x04\x05\x06\x07\x08", 8, little_qword, 0x0807060504030201LL);
}
{
using boost::spirit::karma::big_word;
using boost::spirit::karma::big_dword;
using boost::spirit::karma::big_qword;
test_binary_generator("\x02\x01", 2, big_word(0x0201));
test_binary_generator("\x04\x03\x02\x01", 4, big_dword(0x04030201));
test_binary_generator("\x08\x07\x06\x05\x04\x03\x02\x01", 8, big_qword(0x0807060504030201LL));
test_binary_generator_attr("\x02\x01", 2, big_word, 0x0201);
test_binary_generator_attr("\x04\x03\x02\x01", 4, big_dword, 0x04030201);
test_binary_generator_attr("\x08\x07\x06\x05\x04\x03\x02\x01", 8, big_qword, 0x0807060504030201LL);
}
{
using boost::spirit::karma::int_;
using boost::spirit::karma::string;
using boost::spirit::karma::_1;
using boost::phoenix::ref;
using boost::phoenix::val;
int i = 42;
test_generator("42", int_[_1 = ref(i)]);
test_generator("abc", string[_1 = val("abc")]);
}
{
using boost::spirit::karma::rule;
using boost::spirit::karma::int_;
using boost::spirit::ascii::space;
using boost::spirit::ascii::space_type;
rule<output_iterator_type> r;
r = int_(123);
test_generator("123", r);
rule<output_iterator_type, int()> ra;
ra = int_;
test_generator_attr("123", ra, 123);
rule<output_iterator_type, std::vector<int>(), space_type> rs;
rs = *int_;
std::vector<int> v;
v.push_back(123);
v.push_back(456);
v.push_back(789);
test_generator_attr_delim("123 456 789", rs, space, v);
}
{
using client::num_list;
using boost::spirit::ascii::space_type;
using boost::spirit::ascii::space;
using boost::spirit::int_;
using boost::spirit::karma::grammar;
using boost::spirit::karma::rule;
num_list nlist;
std::vector<int> v;
v.push_back(123);
v.push_back(456);
v.push_back(789);
test_generator_attr_delim("123 , 456 , 789", nlist, space, v);
}
{
using boost::spirit::karma::symbols;
symbols<char, char const*> sym;
sym.add
('a', "Apple")
('b', "Banana")
('o', "Orange")
;
test_generator_attr("Banana", sym, 'b');
}
{
using boost::spirit::utree;
using boost::spirit::utree_type;
using boost::spirit::utf8_symbol_type;
using boost::spirit::karma::as;
using boost::spirit::karma::as_string;
using boost::spirit::karma::char_;
using boost::spirit::karma::double_;
typedef as<utf8_symbol_type> as_symbol_type;
as_symbol_type const as_symbol = as_symbol_type();
utree ut;
ut.push_back("xyz");
ut.push_back(1.23);
test_generator_attr("xyz1.23", as_string[*char_] << double_, ut);
test_generator_attr("xyz1.23", as<std::string>()[*char_] << double_, ut);
ut.clear();
ut.push_back(utf8_symbol_type("xyz"));
ut.push_back(1.23);
test_generator_attr("xyz1.23", as_symbol[*char_] << double_, ut);
test_generator_attr("xyz1.23", as<utf8_symbol_type>()[*char_] << double_, ut);
}
return 0;
}