blob: 1d41c94df3c3c0b42fc7399da5a0bae7a1e5607a [file] [log] [blame]
/*=============================================================================
Copyright (c) 2001-2007 Joel de Guzman
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(BOOST_SPIRIT_LIT_APR_18_2006_1125PM)
#define BOOST_SPIRIT_LIT_APR_18_2006_1125PM
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/skip.hpp>
#include <boost/spirit/home/qi/detail/string_parse.hpp>
#include <boost/spirit/home/support/char_class.hpp>
#include <boost/spirit/home/support/modifier.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/detail/to_narrow.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/fusion/include/value_at.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <string>
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
// parse literal strings
///////////////////////////////////////////////////////////////////////////
template <typename Char>
struct literal_string
{
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef unused_type type; // literal parsers have no attribute
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& component
, Iterator& first, Iterator const& last
, Context& /*context*/, Skipper const& skipper
, Attribute& attr)
{
qi::skip(first, last, skipper);
return detail::string_parse(
fusion::at_c<0>(component.elements)
, first
, last
, attr
);
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return std::string("\"")
+ spirit::detail::to_narrow_string(
fusion::at_c<0>(component.elements))
+ std::string("\"")
;
}
};
///////////////////////////////////////////////////////////////////////////
// parse lazy strings
///////////////////////////////////////////////////////////////////////////
struct lazy_string
{
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef typename
result_of::subject<Component>::type
subject_type;
typedef typename
remove_reference<
typename boost::result_of<subject_type(unused_type, Context)>::type
>::type
type;
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& component
, Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr)
{
qi::skip(first, last, skipper);
return detail::string_parse(
fusion::at_c<0>(component.elements)(unused, context)
, first
, last
, attr
);
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return std::string("\"")
+ spirit::detail::to_narrow_string(
fusion::at_c<0>(component.elements)(unused, ctx))
+ std::string("\"")
;
}
};
///////////////////////////////////////////////////////////////////////////
// no_case literal_string version
///////////////////////////////////////////////////////////////////////////
template <typename Char>
struct no_case_literal_string
{
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef unused_type type; // literal parsers have no attribute
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& component
, Iterator& first, Iterator const& last
, Context& /*context*/, Skipper const& skipper
, Attribute& attr)
{
qi::skip(first, last, skipper);
return detail::string_parse(
fusion::at_c<0>(component.elements)
, fusion::at_c<1>(component.elements)
, first
, last
, attr
);
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return std::string("case-insensitive \"")
+ spirit::detail::to_narrow_string(
fusion::at_c<0>(component.elements))
+ std::string("\"")
;
}
};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// no_case_literal_string generator
///////////////////////////////////////////////////////////////////////////
template <
typename Domain, typename Elements, typename Modifier, typename Char
>
struct make_modified_component<
Domain, qi::literal_string<Char>, Elements, Modifier
, typename enable_if<
is_member_of_modifier<Modifier, spirit::char_class::no_case_base_tag>
>::type
>
{
typedef std::basic_string<Char> string_type;
typedef fusion::vector<string_type, string_type> vector_type;
typedef
component<qi::domain, qi::no_case_literal_string<Char>, vector_type>
type;
static type
call(Elements const& elements)
{
typedef typename Modifier::char_set char_set;
Char const* in = fusion::at_c<0>(elements);
string_type lo(in);
string_type hi(in);
typename string_type::iterator loi = lo.begin();
typename string_type::iterator hii = hi.begin();
for (; loi != lo.end(); ++loi, ++hii, ++in)
{
*loi = char_set::tolower(*loi);
*hii = char_set::toupper(*hii);
}
return type(vector_type(lo, hi));
}
};
}}}
#endif