/** * Copyright (c) 2011 Ubimet * * 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 #include #include #include #include #include #include using namespace boost::assign; struct float_data { float f; double d; std::vector vf; std::vector vd; bool operator==(const float_data &rhs) const { return f == rhs.f && d == rhs.d && std::equal(vf.begin(), vf.end(), rhs.vf.begin()) && std::equal(vd.begin(), vd.end(), rhs.vd.begin()); } }; BOOST_FUSION_ADAPT_STRUCT ( float_data, (float, f) (double, d) (std::vector, vf) (std::vector, vd) ) template struct float_parser: boost::spirit::qi::grammar { float_parser(): float_parser::base_type(start) { using boost::spirit::byte_; using boost::spirit::bin_float; using boost::spirit::big_bin_float; using boost::spirit::little_bin_float; using boost::spirit::bin_double; using boost::spirit::big_bin_double; using boost::spirit::little_bin_double; using boost::spirit::repeat; start = ( bin_float(1.0f) >> big_bin_float(1.0f) >> little_bin_float(1.0f) >> bin_double(1.0) >> big_bin_double(1.0) >> little_bin_double(1.0) ) >> ( bin_float >> bin_double >> repeat(7)[bin_float] >> repeat(5)[bin_double] ) ; } boost::spirit::qi::rule start; }; template struct float_generator: boost::spirit::karma::grammar { float_generator(): float_generator::base_type(start) { using boost::spirit::byte_; using boost::spirit::bin_float; using boost::spirit::big_bin_float; using boost::spirit::little_bin_float; using boost::spirit::bin_double; using boost::spirit::big_bin_double; using boost::spirit::little_bin_double; start = ( bin_float(1.0f) << big_bin_float(1.0f) << little_bin_float(1.0f) << bin_double(1.0) << big_bin_double(1.0) << little_bin_double(1.0) ) << ( bin_float << bin_double << *bin_float << *bin_double ) ; } boost::spirit::karma::rule start; }; int main() { std::ofstream out("float.bin", std::ios::binary | std::ios::trunc); if(!out) { std::cerr << "Failed to open output file\n"; return 1; } typedef std::ostream_iterator iterator; typedef float_generator float_generator; float_generator fg; float_data fd1; fd1.f = 3.1416f; // Pi. fd1.d = 1.41421356; // Sqrt(2) fd1.vf += 1.0f, 1.0f, 2.0f, 3.0f, 5.0f, 8.0f, 13.0f; // Fibonacci. fd1.vd += 2.0, 3.0, 5.0, 7.0, 11.0; // Primes. bool result = boost::spirit::karma::generate(iterator(out), fg, fd1); out.close(); if(!result) { std::cerr << "Failed to generate\n"; return 1; } std::ifstream in("float.bin", std::ios::binary); if(!in) { std::cerr << "Failed to open input file\n"; return 1; } namespace spirit = boost::spirit; typedef std::istreambuf_iterator base_iterator_type; spirit::multi_pass first = spirit::make_default_multi_pass(base_iterator_type(in)); spirit::multi_pass last = spirit::make_default_multi_pass(base_iterator_type()); typedef float_parser > float_parser; float_parser fp; float_data fd2; bool result2 = parse(first, last, fp, fd2); in.close(); if(!result2 || first != last) { std::cerr << "Failed to parse\n"; return 1; } assert(fd2 == fd1); return 0; }