metaparse/example/rational/main.cpp
2017-04-20 16:35:06 +02:00

98 lines
2.4 KiB
C++

// Copyright Abel Sinkovics (abel@sinkovics.hu) 2015.
// 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/metaparse/string.hpp>
#include <boost/metaparse/sequence_apply.hpp>
#include <boost/metaparse/last_of.hpp>
#include <boost/metaparse/int_.hpp>
#include <boost/metaparse/token.hpp>
#include <boost/metaparse/lit_c.hpp>
#include <boost/metaparse/one_of.hpp>
#include <boost/metaparse/empty.hpp>
#include <boost/metaparse/entire_input.hpp>
#include <boost/metaparse/build_parser.hpp>
#include <boost/rational.hpp>
#include <boost/config.hpp>
#include <boost/mpl/int.hpp>
#include <iostream>
using boost::metaparse::sequence_apply2;
using boost::metaparse::last_of;
using boost::metaparse::int_;
using boost::metaparse::token;
using boost::metaparse::lit_c;
using boost::metaparse::one_of;
using boost::metaparse::empty;
using boost::metaparse::entire_input;
using boost::metaparse::build_parser;
template <class Num, class Denom>
struct rational
{
typedef rational type;
static boost::rational<int> run()
{
return boost::rational<int>(Num::type::value, Denom::type::value);
}
};
typedef
sequence_apply2<
rational,
token<int_>,
one_of<
last_of<lit_c<'/'>, token<int_> >,
empty<boost::mpl::int_<1> >
>
>
rational_grammar;
typedef build_parser<entire_input<rational_grammar> > rational_parser;
#ifdef RATIONAL
# error RATIONAL already defined
#endif
#define RATIONAL(s) \
(::rational_parser::apply<BOOST_METAPARSE_STRING(s)>::type::run())
#if BOOST_METAPARSE_STD < 2011
int main()
{
std::cout << "Please use a compiler that supports constexpr" << std::endl;
}
#else
int main()
{
const boost::rational<int> r1 = RATIONAL("1/3");
const boost::rational<int> r2 = RATIONAL("4/4");
const boost::rational<int> r3 = RATIONAL("1");
const boost::rational<int> r4 = RATIONAL("13/11");
// Uncommenting the following line generates a compilation error. On a
// number of platforms the error report contains the following (or something
// similar):
// x__________________PARSING_FAILED__________________x<1, 3, digit_expected>
// where 1, 3 is the location of the error inside the string literal.
// const boost::rational<int> r5 = RATIONAL("7/");
std::cout
<< r1 << std::endl
<< r2 << std::endl
<< r3 << std::endl
<< r4 << std::endl;
}
#endif