Imported existing code
This commit is contained in:
404
libraries/include/boost/spirit/home/qi/string/detail/tst.hpp
Normal file
404
libraries/include/boost/spirit/home/qi/string/detail/tst.hpp
Normal file
@@ -0,0 +1,404 @@
|
||||
/*=============================================================================
|
||||
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_TST_MARCH_09_2007_0905AM)
|
||||
#define BOOST_SPIRIT_TST_MARCH_09_2007_0905AM
|
||||
|
||||
#include <boost/call_traits.hpp>
|
||||
#include <boost/detail/iterator.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi { namespace detail
|
||||
{
|
||||
// This file contains low level TST routines, not for
|
||||
// public consumption.
|
||||
|
||||
template <typename Char, typename T>
|
||||
struct tst_node
|
||||
{
|
||||
tst_node(Char id)
|
||||
: id(id), data(0), lt(0), eq(0), gt(0)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Alloc>
|
||||
static void
|
||||
destruct_node(tst_node* p, Alloc* alloc)
|
||||
{
|
||||
if (p)
|
||||
{
|
||||
if (p->data)
|
||||
alloc->delete_data(p->data);
|
||||
destruct_node(p->lt, alloc);
|
||||
destruct_node(p->eq, alloc);
|
||||
destruct_node(p->gt, alloc);
|
||||
alloc->delete_node(p);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Alloc>
|
||||
static tst_node*
|
||||
clone_node(tst_node* p, Alloc* alloc)
|
||||
{
|
||||
if (p)
|
||||
{
|
||||
tst_node* clone = alloc->new_node(p->id);
|
||||
if (p->data)
|
||||
clone->data = alloc->new_data(*p->data);
|
||||
clone->lt = clone_node(p->lt, alloc);
|
||||
clone->eq = clone_node(p->eq, alloc);
|
||||
clone->gt = clone_node(p->gt, alloc);
|
||||
return clone;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Filter>
|
||||
static T*
|
||||
find(tst_node* start, Iterator& first, Iterator last, Filter filter)
|
||||
{
|
||||
if (first == last)
|
||||
return false;
|
||||
|
||||
Iterator i = first;
|
||||
Iterator latest = first;
|
||||
tst_node* p = start;
|
||||
T* found = 0;
|
||||
|
||||
while (p && i != last)
|
||||
{
|
||||
typename
|
||||
boost::detail::iterator_traits<Iterator>::value_type
|
||||
c = filter(*i); // filter only the input
|
||||
|
||||
if (c == p->id)
|
||||
{
|
||||
if (p->data)
|
||||
{
|
||||
found = p->data;
|
||||
latest = i;
|
||||
}
|
||||
p = p->eq;
|
||||
i++;
|
||||
}
|
||||
else if (c < p->id)
|
||||
{
|
||||
p = p->lt;
|
||||
}
|
||||
else
|
||||
{
|
||||
p = p->gt;
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
first = ++latest; // one past the last matching char
|
||||
return found;
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Alloc>
|
||||
static bool
|
||||
add(
|
||||
tst_node*& start
|
||||
, Iterator first
|
||||
, Iterator last
|
||||
, typename boost::call_traits<T>::param_type val
|
||||
, Alloc* alloc)
|
||||
{
|
||||
if (first == last)
|
||||
return false;
|
||||
|
||||
tst_node** pp = &start;
|
||||
while (true)
|
||||
{
|
||||
typename
|
||||
boost::detail::iterator_traits<Iterator>::value_type
|
||||
c = *first;
|
||||
|
||||
if (*pp == 0)
|
||||
*pp = alloc->new_node(c);
|
||||
tst_node* p = *pp;
|
||||
|
||||
if (c == p->id)
|
||||
{
|
||||
if (++first == last)
|
||||
{
|
||||
if (p->data == 0)
|
||||
{
|
||||
p->data = alloc->new_data(val);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
pp = &p->eq;
|
||||
}
|
||||
else if (c < p->id)
|
||||
{
|
||||
pp = &p->lt;
|
||||
}
|
||||
else
|
||||
{
|
||||
pp = &p->gt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Alloc>
|
||||
static void
|
||||
remove(tst_node*& p, Iterator first, Iterator last, Alloc* alloc)
|
||||
{
|
||||
if (p == 0 || first == last)
|
||||
return;
|
||||
|
||||
typename
|
||||
boost::detail::iterator_traits<Iterator>::value_type
|
||||
c = *first;
|
||||
|
||||
if (c == p->id)
|
||||
{
|
||||
if (++first == last)
|
||||
{
|
||||
if (p->data)
|
||||
{
|
||||
alloc->delete_data(p->data);
|
||||
p->data = 0;
|
||||
}
|
||||
}
|
||||
remove(p->eq, first, last, alloc);
|
||||
}
|
||||
else if (c < p->id)
|
||||
{
|
||||
remove(p->lt, first, last, alloc);
|
||||
}
|
||||
else
|
||||
{
|
||||
remove(p->gt, first, last, alloc);
|
||||
}
|
||||
|
||||
if (p->lt == 0 && p->eq == 0 && p->gt == 0)
|
||||
{
|
||||
alloc->delete_node(p);
|
||||
p = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
static void
|
||||
for_each(tst_node* p, std::basic_string<Char> prefix, F f)
|
||||
{
|
||||
if (p)
|
||||
{
|
||||
for_each(p->lt, prefix, f);
|
||||
std::basic_string<Char> s = prefix + p->id;
|
||||
for_each(p->eq, s, f);
|
||||
if (p->data)
|
||||
f(s, *p->data);
|
||||
for_each(p->gt, prefix, f);
|
||||
}
|
||||
}
|
||||
|
||||
Char id; // the node's identity character
|
||||
T* data; // optional data
|
||||
tst_node* lt; // left pointer
|
||||
tst_node* eq; // middle pointer
|
||||
tst_node* gt; // right pointer
|
||||
};
|
||||
|
||||
/*
|
||||
template <typename Char, typename T>
|
||||
struct tst
|
||||
{
|
||||
typedef Char char_type; // the character type
|
||||
typedef T value_type; // the value associated with each entry
|
||||
typedef tst_node<Char, T> tst_node;
|
||||
|
||||
tst()
|
||||
{
|
||||
}
|
||||
|
||||
~tst()
|
||||
{
|
||||
// Nothing to do here.
|
||||
// The pools do the right thing for us
|
||||
}
|
||||
|
||||
tst(tst const& rhs)
|
||||
{
|
||||
copy(rhs);
|
||||
}
|
||||
|
||||
tst& operator=(tst const& rhs)
|
||||
{
|
||||
return assign(rhs);
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Filter>
|
||||
T* find(Iterator& first, Iterator last, Filter filter) const
|
||||
{
|
||||
if (first != last)
|
||||
{
|
||||
Iterator save = first;
|
||||
typename map_type::const_iterator
|
||||
i = map.find(filter(*first++));
|
||||
if (i == map.end())
|
||||
{
|
||||
first = save;
|
||||
return 0;
|
||||
}
|
||||
if (T* p = detail::find(i->second.root, first, last, filter))
|
||||
{
|
||||
return p;
|
||||
}
|
||||
return i->second.data;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
T* find(Iterator& first, Iterator last) const
|
||||
{
|
||||
return find(first, last, tst_pass_through());
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
bool add(
|
||||
Iterator first
|
||||
, Iterator last
|
||||
, typename boost::call_traits<T>::param_type val)
|
||||
{
|
||||
if (first != last)
|
||||
{
|
||||
map_data x = {0, 0};
|
||||
std::pair<typename map_type::iterator, bool>
|
||||
r = map.insert(std::pair<Char, map_data>(*first++, x));
|
||||
|
||||
if (first != last)
|
||||
{
|
||||
return detail::add(r.first->second.root, first, last, val, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (r.first->second.data)
|
||||
return false;
|
||||
r.first->second.data = this->new_data(val);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
void remove(Iterator first, Iterator last)
|
||||
{
|
||||
if (first != last)
|
||||
{
|
||||
typename map_type::iterator i = map.find(*first++);
|
||||
if (i != map.end())
|
||||
{
|
||||
if (first != last)
|
||||
{
|
||||
detail::remove(i->second.root, first, last, this);
|
||||
}
|
||||
else if (i->second.data)
|
||||
{
|
||||
this->delete_data(i->second.data);
|
||||
i->second.data = 0;
|
||||
}
|
||||
if (i->second.data == 0 && i->second.root == 0)
|
||||
{
|
||||
map.erase(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
BOOST_FOREACH(typename map_type::value_type& x, map)
|
||||
{
|
||||
destruct_node(x.second.root, this);
|
||||
if (x.second.data)
|
||||
this->delete_data(x.second.data);
|
||||
}
|
||||
map.clear();
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
void for_each(F f) const
|
||||
{
|
||||
BOOST_FOREACH(typename map_type::value_type const& x, map)
|
||||
{
|
||||
std::basic_string<Char> s(1, x.first);
|
||||
detail::for_each(x.second.root, s, f);
|
||||
if (x.second.data)
|
||||
f(s, *x.second.data);
|
||||
}
|
||||
}
|
||||
|
||||
tst_node* new_node(Char id)
|
||||
{
|
||||
return node_pool.construct(id);
|
||||
}
|
||||
|
||||
T* new_data(typename boost::call_traits<T>::param_type val)
|
||||
{
|
||||
return data_pool.construct(val);
|
||||
}
|
||||
|
||||
void delete_node(tst_node* p)
|
||||
{
|
||||
node_pool.destroy(p);
|
||||
}
|
||||
|
||||
void delete_data(T* p)
|
||||
{
|
||||
data_pool.destroy(p);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
struct map_data
|
||||
{
|
||||
tst_node* root;
|
||||
T* data;
|
||||
};
|
||||
|
||||
typedef unordered_map<Char, map_data> map_type;
|
||||
|
||||
void copy(tst const& rhs)
|
||||
{
|
||||
BOOST_FOREACH(typename map_type::value_type const& x, rhs.map)
|
||||
{
|
||||
map_data xx = {clone_node(x.second.root, this), 0};
|
||||
if (x.second.data)
|
||||
xx.data = data_pool.construct(*x.second.data);
|
||||
map[x.first] = xx;
|
||||
}
|
||||
}
|
||||
|
||||
tst& assign(tst const& rhs)
|
||||
{
|
||||
if (this != &rhs)
|
||||
{
|
||||
BOOST_FOREACH(typename map_type::value_type& x, map)
|
||||
{
|
||||
destruct_node(x.second.root, this);
|
||||
}
|
||||
map.clear();
|
||||
copy(rhs);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
map_type map;
|
||||
object_pool<tst_node> node_pool;
|
||||
object_pool<T> data_pool;
|
||||
};
|
||||
*/
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
204
libraries/include/boost/spirit/home/qi/string/lit.hpp
Normal file
204
libraries/include/boost/spirit/home/qi/string/lit.hpp
Normal file
@@ -0,0 +1,204 @@
|
||||
/*=============================================================================
|
||||
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
|
||||
203
libraries/include/boost/spirit/home/qi/string/meta_grammar.hpp
Normal file
203
libraries/include/boost/spirit/home/qi/string/meta_grammar.hpp
Normal file
@@ -0,0 +1,203 @@
|
||||
/*=============================================================================
|
||||
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_META_GRAMMAR_FEB_03_2007_0356PM)
|
||||
#define BOOST_SPIRIT_META_GRAMMAR_FEB_03_2007_0356PM
|
||||
|
||||
#include <boost/spirit/home/qi/domain.hpp>
|
||||
#include <boost/spirit/home/support/placeholders.hpp>
|
||||
#include <boost/spirit/home/support/meta_grammar.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// forwards
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template<typename Char>
|
||||
struct literal_string;
|
||||
|
||||
struct lazy_string;
|
||||
|
||||
template <typename Filter>
|
||||
struct symbols_director;
|
||||
|
||||
struct string_meta_grammar;
|
||||
|
||||
template <typename Expr, typename Enable>
|
||||
struct is_valid_expr;
|
||||
|
||||
template <typename Expr, typename Enable>
|
||||
struct expr_transform;
|
||||
|
||||
template <typename Lookup>
|
||||
struct symbols_lookup;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// get the director of a string literal type
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
struct extract_char;
|
||||
|
||||
template <typename Char, typename Traits, typename Alloc>
|
||||
struct extract_char<std::basic_string<Char, Traits, Alloc> >
|
||||
{
|
||||
typedef Char type;
|
||||
};
|
||||
|
||||
template <typename Char, int N>
|
||||
struct extract_char<Char[N]>
|
||||
{
|
||||
typedef typename remove_const<Char>::type type;
|
||||
};
|
||||
|
||||
template <typename Char, int N>
|
||||
struct extract_char<Char(&)[N]>
|
||||
{
|
||||
typedef typename remove_const<Char>::type type;
|
||||
};
|
||||
|
||||
template <typename Char>
|
||||
struct extract_char<Char*>
|
||||
{
|
||||
typedef typename remove_const<Char>::type type;
|
||||
};
|
||||
|
||||
template <typename Tag, typename T>
|
||||
struct extract_lit_director;
|
||||
|
||||
template <typename T>
|
||||
struct extract_lit_director<tag::lit, T>
|
||||
{
|
||||
typedef typename extract_char<T>::type char_type;
|
||||
typedef literal_string<char_type> type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct extract_lit_director<tag::wlit, T>
|
||||
{
|
||||
typedef typename extract_char<T>::type char_type;
|
||||
typedef literal_string<char_type> type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// string parser meta-grammars
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// literal strings: "hello"
|
||||
struct string_literal_meta_grammar
|
||||
: proto::or_<
|
||||
meta_grammar::terminal_rule<
|
||||
qi::domain, char const*, literal_string<char> >
|
||||
, meta_grammar::terminal_rule<
|
||||
qi::domain, char*, literal_string<char> >
|
||||
, meta_grammar::terminal_rule<
|
||||
qi::domain, wchar_t const*, literal_string<wchar_t> >
|
||||
, meta_grammar::terminal_rule<
|
||||
qi::domain, wchar_t*, literal_string<wchar_t> >
|
||||
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
// literal strings: "hello"
|
||||
struct basic_string_literal_meta_grammar
|
||||
: proto::or_<
|
||||
proto::terminal<char const*>
|
||||
, proto::terminal<wchar_t const*>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
// std::string(s)
|
||||
struct basic_std_string_meta_grammar
|
||||
: proto::or_<
|
||||
proto::terminal<std::basic_string<char, proto::_, proto::_> >
|
||||
, proto::terminal<std::basic_string<wchar_t, proto::_, proto::_> >
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
// std::string(s)
|
||||
struct std_string_meta_grammar
|
||||
: proto::or_<
|
||||
meta_grammar::terminal_rule<
|
||||
qi::domain
|
||||
, std::basic_string<char, proto::_, proto::_>
|
||||
, literal_string<char> >
|
||||
, meta_grammar::terminal_rule<
|
||||
qi::domain
|
||||
, std::basic_string<wchar_t, proto::_, proto::_>
|
||||
, literal_string<wchar_t> >
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// we use this test to detect if the argument to lit is a callable
|
||||
// function or not. Only types convertible to int or function/
|
||||
// function objects are allowed. Therefore, if T is not convertible
|
||||
// to an int, then we have a function/function object.
|
||||
template <typename T>
|
||||
struct is_not_convertible_to_int
|
||||
: mpl::not_<is_convertible<T, int> >
|
||||
{};
|
||||
}
|
||||
|
||||
// strings: "hello", lit("hello"), lit(str), lit(f), symbols
|
||||
struct string_meta_grammar
|
||||
: proto::or_<
|
||||
string_literal_meta_grammar
|
||||
, std_string_meta_grammar
|
||||
, meta_grammar::compose_function1_eval<
|
||||
proto::function<
|
||||
proto::if_<
|
||||
is_lit_tag<proto::_child, qi::domain>()>
|
||||
, proto::or_<basic_string_literal_meta_grammar, basic_std_string_meta_grammar>
|
||||
>
|
||||
, qi::domain
|
||||
, mpl::identity<extract_lit_director<mpl::_, mpl::_> >
|
||||
>
|
||||
, meta_grammar::function1_rule<
|
||||
qi::domain
|
||||
, tag::lit
|
||||
, lazy_string
|
||||
, proto::if_<
|
||||
detail::is_not_convertible_to_int<proto::_child >() >
|
||||
>
|
||||
, meta_grammar::terminal_rule<
|
||||
qi::domain
|
||||
, symbols_lookup<proto::_>
|
||||
, symbols_director<>
|
||||
>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// These specializations non-intrusively hooks into the RD meta-grammar.
|
||||
// (see qi/meta_grammar.hpp)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Expr>
|
||||
struct is_valid_expr<Expr
|
||||
, typename enable_if<proto::matches<Expr, string_meta_grammar> >::type>
|
||||
: mpl::true_
|
||||
{
|
||||
};
|
||||
|
||||
template <typename Expr>
|
||||
struct expr_transform<Expr
|
||||
, typename enable_if<proto::matches<Expr, string_meta_grammar> >::type>
|
||||
: mpl::identity<string_meta_grammar>
|
||||
{
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
297
libraries/include/boost/spirit/home/qi/string/symbols.hpp
Normal file
297
libraries/include/boost/spirit/home/qi/string/symbols.hpp
Normal file
@@ -0,0 +1,297 @@
|
||||
/*=============================================================================
|
||||
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_SYMBOL_MARCH_11_2007_1055AM)
|
||||
#define BOOST_SPIRIT_SYMBOL_MARCH_11_2007_1055AM
|
||||
|
||||
#include <boost/spirit/home/qi/domain.hpp>
|
||||
#include <boost/spirit/home/qi/skip.hpp>
|
||||
#include <boost/spirit/home/qi/string/tst.hpp>
|
||||
#include <boost/spirit/home/support/modifier.hpp>
|
||||
#include <boost/spirit/home/qi/detail/assign_to.hpp>
|
||||
#include <boost/fusion/include/at.hpp>
|
||||
#include <boost/proto/core.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/type_traits/add_reference.hpp>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4355) // 'this' : used in base member initializer list warning
|
||||
#endif
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
template <typename Filter = tst_pass_through>
|
||||
struct symbols_director
|
||||
{
|
||||
template <typename Component, typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef typename
|
||||
result_of::subject<Component>::type::ptr_type::element_type::value_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)
|
||||
{
|
||||
typedef typename
|
||||
result_of::subject<Component>::type::ptr_type::element_type::value_type
|
||||
value_type;
|
||||
|
||||
qi::skip(first, last, skipper);
|
||||
|
||||
if (value_type* val_ptr
|
||||
= fusion::at_c<0>(component.elements)
|
||||
.lookup->find(first, last, Filter()))
|
||||
{
|
||||
detail::assign_to(*val_ptr, attr);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Component, typename Context>
|
||||
static std::string what(Component const& component, Context const& ctx)
|
||||
{
|
||||
// perhaps we should show some of the contents?
|
||||
return "symbols";
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Lookup>
|
||||
struct symbols_lookup
|
||||
{
|
||||
typedef shared_ptr<Lookup> ptr_type;
|
||||
ptr_type lookup;
|
||||
};
|
||||
|
||||
template <typename Char, typename T, typename Lookup = tst<Char, T> >
|
||||
struct symbols
|
||||
: proto::extends<
|
||||
typename proto::terminal<symbols_lookup<Lookup> >::type
|
||||
, symbols<Char, T>
|
||||
>
|
||||
{
|
||||
typedef Char char_type; // the character type
|
||||
typedef T value_type; // the value associated with each entry
|
||||
typedef shared_ptr<Lookup> ptr_type;
|
||||
|
||||
symbols()
|
||||
: add(*this)
|
||||
, remove(*this)
|
||||
{
|
||||
proto::child(*this).lookup = ptr_type(new Lookup());
|
||||
}
|
||||
|
||||
template <typename Symbols>
|
||||
symbols(Symbols const& syms)
|
||||
: add(*this)
|
||||
, remove(*this)
|
||||
{
|
||||
proto::child(*this).lookup = ptr_type(new Lookup());
|
||||
typename range_const_iterator<Symbols>::type si = boost::begin(syms);
|
||||
while (si != boost::end(syms))
|
||||
add(*si++);
|
||||
}
|
||||
|
||||
template <typename Symbols, typename Data>
|
||||
symbols(Symbols const& syms, Data const& data)
|
||||
: add(*this)
|
||||
, remove(*this)
|
||||
{
|
||||
proto::child(*this).lookup = ptr_type(new Lookup());
|
||||
typename range_const_iterator<Symbols>::type si = boost::begin(syms);
|
||||
typename range_const_iterator<Data>::type di = boost::begin(data);
|
||||
while (si != boost::end(syms))
|
||||
add(*si++, *di++);
|
||||
}
|
||||
|
||||
symbols&
|
||||
operator=(symbols const& rhs)
|
||||
{
|
||||
proto::child(*this) = proto::child(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
lookup()->clear();
|
||||
}
|
||||
|
||||
struct adder;
|
||||
struct remover;
|
||||
|
||||
adder const&
|
||||
operator=(Char const* str)
|
||||
{
|
||||
lookup()->clear();
|
||||
return add(str);
|
||||
}
|
||||
|
||||
adder const&
|
||||
operator+=(Char const* str)
|
||||
{
|
||||
return add(str);
|
||||
}
|
||||
|
||||
remover const&
|
||||
operator-=(Char const* str)
|
||||
{
|
||||
return remove(str);
|
||||
}
|
||||
|
||||
ptr_type lookup() const
|
||||
{
|
||||
return proto::child(*this).lookup;
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
void for_each(F f) const
|
||||
{
|
||||
lookup()->for_each(f);
|
||||
}
|
||||
|
||||
struct adder
|
||||
{
|
||||
template <typename, typename = unused_type, typename = unused_type>
|
||||
struct result { typedef adder const& type; };
|
||||
|
||||
adder(symbols& sym)
|
||||
: sym(sym)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
adder const&
|
||||
operator()(Iterator const& first, Iterator const& last, T const& val = T()) const
|
||||
{
|
||||
sym.lookup()->add(first, last, val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
adder const&
|
||||
operator()(Char const* s, T const& val = T()) const
|
||||
{
|
||||
Char const* last = s;
|
||||
while (*last)
|
||||
last++;
|
||||
sym.lookup()->add(s, last, val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
adder const&
|
||||
operator,(Char const* s) const
|
||||
{
|
||||
Char const* last = s;
|
||||
while (*last)
|
||||
last++;
|
||||
sym.lookup()->add(s, last, T());
|
||||
return *this;
|
||||
}
|
||||
|
||||
symbols& sym;
|
||||
};
|
||||
|
||||
struct remover
|
||||
{
|
||||
template <typename, typename = unused_type, typename = unused_type>
|
||||
struct result { typedef adder const& type; };
|
||||
|
||||
remover(symbols& sym)
|
||||
: sym(sym)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
remover const&
|
||||
operator()(Iterator const& first, Iterator const& last) const
|
||||
{
|
||||
sym.lookup()->remove(first, last);
|
||||
return *this;
|
||||
}
|
||||
|
||||
remover const&
|
||||
operator()(Char const* s) const
|
||||
{
|
||||
Char const* last = s;
|
||||
while (*last)
|
||||
last++;
|
||||
sym.lookup()->remove(s, last);
|
||||
return *this;
|
||||
}
|
||||
|
||||
remover const&
|
||||
operator,(Char const* s) const
|
||||
{
|
||||
Char const* last = s;
|
||||
while (*last)
|
||||
last++;
|
||||
sym.lookup()->remove(s, last);
|
||||
return *this;
|
||||
}
|
||||
|
||||
symbols& sym;
|
||||
};
|
||||
|
||||
adder add;
|
||||
remover remove;
|
||||
};
|
||||
}}}
|
||||
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template <typename CharSet>
|
||||
struct no_case_filter
|
||||
{
|
||||
template <typename Char>
|
||||
Char operator()(Char ch) const
|
||||
{
|
||||
return CharSet::tolower(ch);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// generator for no-case symbols
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Domain, typename Elements, typename Modifier>
|
||||
struct make_modified_component<Domain, qi::symbols_director<>, Elements, Modifier
|
||||
, typename enable_if<
|
||||
is_member_of_modifier<Modifier, spirit::char_class::no_case_base_tag>
|
||||
>::type
|
||||
>
|
||||
{
|
||||
typedef detail::no_case_filter<typename Modifier::char_set> filter;
|
||||
typedef component<qi::domain, qi::symbols_director<filter>, Elements> type;
|
||||
|
||||
static type
|
||||
call(Elements const& elements)
|
||||
{
|
||||
// we return the same lookup but this time we use a director
|
||||
// with a filter that converts to lower-case.
|
||||
return elements;
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
133
libraries/include/boost/spirit/home/qi/string/tst.hpp
Normal file
133
libraries/include/boost/spirit/home/qi/string/tst.hpp
Normal file
@@ -0,0 +1,133 @@
|
||||
/*=============================================================================
|
||||
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_TST_JUNE_03_2007_1031AM)
|
||||
#define BOOST_SPIRIT_TST_JUNE_03_2007_1031AM
|
||||
|
||||
#include <boost/spirit/home/qi/string/detail/tst.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
struct tst_pass_through
|
||||
{
|
||||
template <typename Char>
|
||||
Char operator()(Char ch) const
|
||||
{
|
||||
return ch;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char, typename T>
|
||||
struct tst
|
||||
{
|
||||
typedef Char char_type; // the character type
|
||||
typedef T value_type; // the value associated with each entry
|
||||
typedef detail::tst_node<Char, T> node;
|
||||
|
||||
tst()
|
||||
: root(0)
|
||||
{
|
||||
}
|
||||
|
||||
~tst()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
tst(tst const& rhs)
|
||||
: root(0)
|
||||
{
|
||||
copy(rhs);
|
||||
}
|
||||
|
||||
tst& operator=(tst const& rhs)
|
||||
{
|
||||
return assign(rhs);
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Filter>
|
||||
T* find(Iterator& first, Iterator last, Filter filter) const
|
||||
{
|
||||
return node::find(root, first, last, filter);
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
T* find(Iterator& first, Iterator last) const
|
||||
{
|
||||
return find(first, last, tst_pass_through());
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
bool add(
|
||||
Iterator first
|
||||
, Iterator last
|
||||
, typename boost::call_traits<T>::param_type val)
|
||||
{
|
||||
return node::add(root, first, last, val, this);
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
void remove(Iterator first, Iterator last)
|
||||
{
|
||||
node::remove(root, first, last, this);
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
node::destruct_node(root, this);
|
||||
root = 0;
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
void for_each(F f) const
|
||||
{
|
||||
node::for_each(root, std::basic_string<Char>(), f);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
friend struct detail::tst_node<Char, T>;
|
||||
|
||||
void copy(tst const& rhs)
|
||||
{
|
||||
root = node::clone_node(rhs.root, this);
|
||||
}
|
||||
|
||||
tst& assign(tst const& rhs)
|
||||
{
|
||||
if (this != &rhs)
|
||||
{
|
||||
clear();
|
||||
copy(rhs);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
node* root;
|
||||
|
||||
node* new_node(Char id)
|
||||
{
|
||||
return new node(id);
|
||||
}
|
||||
|
||||
T* new_data(typename boost::call_traits<T>::param_type val)
|
||||
{
|
||||
return new T(val);
|
||||
}
|
||||
|
||||
void delete_node(node* p)
|
||||
{
|
||||
delete p;
|
||||
}
|
||||
|
||||
void delete_data(T* p)
|
||||
{
|
||||
delete p;
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
211
libraries/include/boost/spirit/home/qi/string/tst_map.hpp
Normal file
211
libraries/include/boost/spirit/home/qi/string/tst_map.hpp
Normal file
@@ -0,0 +1,211 @@
|
||||
/*=============================================================================
|
||||
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_TST_MAP_JUNE_03_2007_1143AM)
|
||||
#define BOOST_SPIRIT_TST_MAP_JUNE_03_2007_1143AM
|
||||
|
||||
#include <boost/spirit/home/qi/string/detail/tst.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include <boost/pool/object_pool.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
struct tst_pass_through; // declared in tst.hpp
|
||||
|
||||
template <typename Char, typename T>
|
||||
struct tst_map
|
||||
{
|
||||
typedef Char char_type; // the character type
|
||||
typedef T value_type; // the value associated with each entry
|
||||
typedef detail::tst_node<Char, T> node;
|
||||
|
||||
tst_map()
|
||||
{
|
||||
}
|
||||
|
||||
~tst_map()
|
||||
{
|
||||
// Nothing to do here.
|
||||
// The pools do the right thing for us
|
||||
}
|
||||
|
||||
tst_map(tst_map const& rhs)
|
||||
{
|
||||
copy(rhs);
|
||||
}
|
||||
|
||||
tst_map& operator=(tst_map const& rhs)
|
||||
{
|
||||
return assign(rhs);
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Filter>
|
||||
T* find(Iterator& first, Iterator last, Filter filter) const
|
||||
{
|
||||
if (first != last)
|
||||
{
|
||||
Iterator save = first;
|
||||
typename map_type::const_iterator
|
||||
i = map.find(filter(*first++));
|
||||
if (i == map.end())
|
||||
{
|
||||
first = save;
|
||||
return 0;
|
||||
}
|
||||
if (T* p = node::find(i->second.root, first, last, filter))
|
||||
{
|
||||
return p;
|
||||
}
|
||||
return i->second.data;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
T* find(Iterator& first, Iterator last) const
|
||||
{
|
||||
return find(first, last, tst_pass_through());
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
bool add(
|
||||
Iterator first
|
||||
, Iterator last
|
||||
, typename boost::call_traits<T>::param_type val)
|
||||
{
|
||||
if (first != last)
|
||||
{
|
||||
map_data x = {0, 0};
|
||||
std::pair<typename map_type::iterator, bool>
|
||||
r = map.insert(std::pair<Char, map_data>(*first++, x));
|
||||
|
||||
if (first != last)
|
||||
{
|
||||
return node::add(r.first->second.root, first, last, val, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (r.first->second.data)
|
||||
return false;
|
||||
r.first->second.data = this->new_data(val);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
void remove(Iterator first, Iterator last)
|
||||
{
|
||||
if (first != last)
|
||||
{
|
||||
typename map_type::iterator i = map.find(*first++);
|
||||
if (i != map.end())
|
||||
{
|
||||
if (first != last)
|
||||
{
|
||||
node::remove(i->second.root, first, last, this);
|
||||
}
|
||||
else if (i->second.data)
|
||||
{
|
||||
this->delete_data(i->second.data);
|
||||
i->second.data = 0;
|
||||
}
|
||||
if (i->second.data == 0 && i->second.root == 0)
|
||||
{
|
||||
map.erase(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
BOOST_FOREACH(typename map_type::value_type& x, map)
|
||||
{
|
||||
node::destruct_node(x.second.root, this);
|
||||
if (x.second.data)
|
||||
this->delete_data(x.second.data);
|
||||
}
|
||||
map.clear();
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
void for_each(F f) const
|
||||
{
|
||||
BOOST_FOREACH(typename map_type::value_type const& x, map)
|
||||
{
|
||||
std::basic_string<Char> s(1, x.first);
|
||||
node::for_each(x.second.root, s, f);
|
||||
if (x.second.data)
|
||||
f(s, *x.second.data);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
friend struct detail::tst_node<Char, T>;
|
||||
|
||||
struct map_data
|
||||
{
|
||||
node* root;
|
||||
T* data;
|
||||
};
|
||||
|
||||
typedef unordered_map<Char, map_data> map_type;
|
||||
|
||||
void copy(tst_map const& rhs)
|
||||
{
|
||||
BOOST_FOREACH(typename map_type::value_type const& x, rhs.map)
|
||||
{
|
||||
map_data xx = {node::clone_node(x.second.root, this), 0};
|
||||
if (x.second.data)
|
||||
xx.data = data_pool.construct(*x.second.data);
|
||||
map[x.first] = xx;
|
||||
}
|
||||
}
|
||||
|
||||
tst_map& assign(tst_map const& rhs)
|
||||
{
|
||||
if (this != &rhs)
|
||||
{
|
||||
BOOST_FOREACH(typename map_type::value_type& x, map)
|
||||
{
|
||||
node::destruct_node(x.second.root, this);
|
||||
}
|
||||
map.clear();
|
||||
copy(rhs);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
node* new_node(Char id)
|
||||
{
|
||||
return node_pool.construct(id);
|
||||
}
|
||||
|
||||
T* new_data(typename boost::call_traits<T>::param_type val)
|
||||
{
|
||||
return data_pool.construct(val);
|
||||
}
|
||||
|
||||
void delete_node(node* p)
|
||||
{
|
||||
node_pool.destroy(p);
|
||||
}
|
||||
|
||||
void delete_data(T* p)
|
||||
{
|
||||
data_pool.destroy(p);
|
||||
}
|
||||
|
||||
map_type map;
|
||||
object_pool<node> node_pool;
|
||||
object_pool<T> data_pool;
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user