blob: 987e4f7f81cf1d47bd13f392bbb7477263507b5e [file] [log] [blame]
/*=============================================================================
Copyright (c) 2001-2010 Hartmut Kaiser
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)
==============================================================================*/
#if !defined(SPIRIT_QI_BOOL_SEP_29_2009_0709AM)
#define SPIRIT_QI_BOOL_SEP_29_2009_0709AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/skip_over.hpp>
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/qi/numeric/bool_policies.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/detail/workaround.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_terminal<qi::domain, tag::bool_> // enables bool_
: mpl::true_ {};
template <>
struct use_terminal<qi::domain, tag::true_> // enables true_
: mpl::true_ {};
template <>
struct use_terminal<qi::domain, tag::false_> // enables false_
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace qi
{
using spirit::bool_;
using spirit::bool__type;
using spirit::true_;
using spirit::true__type;
using spirit::false_;
using spirit::false__type;
namespace detail
{
template <typename T, typename Policies>
struct bool_impl
{
template <typename Iterator, typename Attribute>
static bool parse(Iterator& first, Iterator const& last
, Attribute& attr, Policies const& p, bool allow_true = true
, bool disallow_false = false)
{
if (first == last)
return false;
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
p; // suppresses warning: C4100: 'p' : unreferenced formal parameter
#endif
return (allow_true && p.parse_true(first, last, attr)) ||
(!disallow_false && p.parse_false(first, last, attr));
}
};
}
///////////////////////////////////////////////////////////////////////////
// This actual boolean parser
///////////////////////////////////////////////////////////////////////////
template <
typename T = bool
, typename Policies = bool_policies<T> >
struct bool_parser_impl
: primitive_parser<bool_parser_impl<T, Policies> >
{
template <typename Context, typename Iterator>
struct attribute
{
typedef T type;
};
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context& /*context*/, Skipper const& skipper
, Attribute& attr) const
{
qi::skip_over(first, last, skipper);
return detail::bool_impl<T, Policies>::
parse(first, last, attr, Policies());
}
template <typename Context>
info what(Context& /*context*/) const
{
return info("boolean");
}
};
template <
typename T = bool
, typename Policies = bool_policies<T> >
struct bool_parser_literal_impl
: primitive_parser<bool_parser_literal_impl<T, Policies> >
{
template <typename Context, typename Iterator>
struct attribute
{
typedef T type;
};
bool_parser_literal_impl(typename add_const<T>::type n)
: n_(n)
{}
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context& /*context*/, Skipper const& skipper
, Attribute& attr) const
{
qi::skip_over(first, last, skipper);
return detail::bool_impl<T, Policies>::
parse(first, last, attr, Policies(), n_, n_);
}
template <typename Context>
info what(Context& /*context*/) const
{
return info("boolean");
}
T n_;
};
///////////////////////////////////////////////////////////////////////////
// bool_parser is the class that the user can instantiate directly
///////////////////////////////////////////////////////////////////////////
template <
typename T
, typename Policies = bool_policies<T> >
struct bool_parser
: proto::terminal<bool_parser_impl<T, Policies> >::type
{};
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Modifiers>
struct make_primitive<tag::bool_, Modifiers>
{
typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
typedef typename mpl::if_<
no_case
, bool_parser_impl<bool, no_case_bool_policies<> >
, bool_parser_impl<> >::type
result_type;
result_type operator()(unused_type, unused_type) const
{
return result_type();
}
};
namespace detail
{
template <typename Modifiers, bool b>
struct make_literal_bool
{
typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
typedef typename mpl::if_<
no_case
, bool_parser_literal_impl<bool, no_case_bool_policies<> >
, bool_parser_literal_impl<> >::type
result_type;
result_type operator()(unused_type, unused_type) const
{
return result_type(b);
}
};
}
template <typename Modifiers>
struct make_primitive<tag::false_, Modifiers>
: detail::make_literal_bool<Modifiers, false>
{};
template <typename Modifiers>
struct make_primitive<tag::true_, Modifiers>
: detail::make_literal_bool<Modifiers, true>
{};
}}}
#endif