stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork

This commit is contained in:
2026-02-24 18:38:47 +00:00
parent da8c28aaeb
commit 65cb2619a7
13106 changed files with 2484322 additions and 1804 deletions
@@ -0,0 +1,213 @@
/*=============================================================================
Copyright (c) 2001-2011 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
#if defined(_MSC_VER)
#pragma once
#endif
#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 0;
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 T*
add(
tst_node*& start
, Iterator first
, Iterator last
, typename boost::call_traits<T>::param_type val
, Alloc* alloc)
{
if (first == last)
return 0;
tst_node** pp = &start;
for(;;)
{
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 p->data;
}
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->data == 0 && 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
};
}}}}
#endif
@@ -0,0 +1,312 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2010 Bryce Lelbach
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
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/skip_over.hpp>
#include <boost/spirit/home/qi/detail/string_parse.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/auxiliary/lazy.hpp>
#include <boost/spirit/home/qi/detail/enable_lit.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/char_class.hpp>
#include <boost/spirit/home/support/modify.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/string_traits.hpp>
#include <boost/spirit/home/support/detail/get_encoding.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/fusion/include/value_at.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/if.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/utility/enable_if.hpp>
#include <string>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct use_terminal<qi::domain, T
, typename enable_if<traits::is_string<T> >::type> // enables strings
: mpl::true_ {};
template <typename CharEncoding, typename A0>
struct use_terminal<qi::domain
, terminal_ex<
tag::char_code<tag::string, CharEncoding> // enables string(str)
, fusion::vector1<A0> >
> : traits::is_string<A0> {};
template <typename CharEncoding> // enables string(f)
struct use_lazy_terminal<
qi::domain
, tag::char_code<tag::string, CharEncoding>
, 1 /*arity*/
> : mpl::true_ {};
// enables lit(...)
template <typename A0>
struct use_terminal<qi::domain
, terminal_ex<tag::lit, fusion::vector1<A0> >
, typename enable_if<traits::is_string<A0> >::type>
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace qi
{
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::lit;
#endif
using spirit::lit_type;
///////////////////////////////////////////////////////////////////////////
// Parse for literal strings
///////////////////////////////////////////////////////////////////////////
template <typename String, bool no_attribute>
struct literal_string
: primitive_parser<literal_string<String, no_attribute> >
{
typedef typename
remove_const<typename traits::char_type_of<String>::type>::type
char_type;
typedef std::basic_string<char_type> string_type;
literal_string(typename add_reference<String>::type str_)
: str(str_)
{}
template <typename Context, typename Iterator>
struct attribute
{
typedef typename mpl::if_c<
no_attribute, unused_type, string_type>::type
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::string_parse(str, first, last, attr_);
}
template <typename Context>
info what(Context& /*context*/) const
{
return info("literal-string", str);
}
String str;
private:
// silence MSVC warning C4512: assignment operator could not be generated
literal_string& operator= (literal_string const&);
};
template <typename String, bool no_attribute>
struct no_case_literal_string
: primitive_parser<no_case_literal_string<String, no_attribute> >
{
typedef typename
remove_const<typename traits::char_type_of<String>::type>::type
char_type;
typedef std::basic_string<char_type> string_type;
template <typename CharEncoding>
no_case_literal_string(char_type const* in, CharEncoding encoding)
: str_lo(in)
, str_hi(in)
{
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
encoding; // suppresses warning: C4100: 'encoding' : unreferenced formal parameter
#endif
typename string_type::iterator loi = str_lo.begin();
typename string_type::iterator hii = str_hi.begin();
for (; loi != str_lo.end(); ++loi, ++hii, ++in)
{
typedef typename CharEncoding::char_type encoded_char_type;
*loi = static_cast<char_type>(encoding.tolower(encoded_char_type(*loi)));
*hii = static_cast<char_type>(encoding.toupper(encoded_char_type(*hii)));
}
}
template <typename Context, typename Iterator>
struct attribute
{
typedef typename mpl::if_c<
no_attribute, unused_type, string_type>::type
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::string_parse(str_lo, str_hi, first, last, attr_);
}
template <typename Context>
info what(Context& /*context*/) const
{
return info("no-case-literal-string", str_lo);
}
string_type str_lo, str_hi;
};
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Modifiers>
struct make_primitive<T, Modifiers
, typename enable_if<traits::is_string<T> >::type>
{
typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
typedef typename add_const<T>::type const_string;
typedef typename mpl::if_<
no_case
, no_case_literal_string<const_string, true>
, literal_string<const_string, true> >::type
result_type;
result_type operator()(
typename add_reference<const_string>::type str, unused_type) const
{
return op(str, no_case());
}
template <typename String>
result_type op(String const& str, mpl::false_) const
{
return result_type(str);
}
template <typename String>
result_type op(String const& str, mpl::true_) const
{
typename spirit::detail::get_encoding<Modifiers,
spirit::char_encoding::standard>::type encoding;
return result_type(traits::get_c_string(str), encoding);
}
};
// lit("...")
template <typename Modifiers, typename A0>
struct make_primitive<
terminal_ex<tag::lit, fusion::vector1<A0> >
, Modifiers
, typename enable_if<traits::is_string<A0> >::type>
{
typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
typedef typename add_const<A0>::type const_string;
typedef typename mpl::if_<
no_case
, no_case_literal_string<const_string, true>
, literal_string<const_string, true> >::type
result_type;
template <typename Terminal>
result_type operator()(Terminal const& term, unused_type) const
{
return op(fusion::at_c<0>(term.args), no_case());
}
template <typename String>
result_type op(String const& str, mpl::false_) const
{
return result_type(str);
}
template <typename String>
result_type op(String const& str, mpl::true_) const
{
typedef typename traits::char_encoding_from_char<
typename traits::char_type_of<A0>::type>::type encoding_type;
typename spirit::detail::get_encoding<Modifiers,
encoding_type>::type encoding;
return result_type(traits::get_c_string(str), encoding);
}
};
///////////////////////////////////////////////////////////////////////////
// string("...")
template <typename CharEncoding, typename Modifiers, typename A0>
struct make_primitive<
terminal_ex<
tag::char_code<tag::string, CharEncoding>
, fusion::vector1<A0> >
, Modifiers>
{
typedef CharEncoding encoding;
typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
typedef typename add_const<A0>::type const_string;
typedef typename mpl::if_<
no_case
, no_case_literal_string<const_string, false>
, literal_string<const_string, false> >::type
result_type;
template <typename Terminal>
result_type operator()(Terminal const& term, unused_type) const
{
return op(fusion::at_c<0>(term.args), no_case());
}
template <typename String>
result_type op(String const& str, mpl::false_) const
{
return result_type(str);
}
template <typename String>
result_type op(String const& str, mpl::true_) const
{
return result_type(traits::get_c_string(str), encoding());
}
};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename String, bool no_attribute, typename Attribute
,typename Context, typename Iterator>
struct handles_container<qi::literal_string<String, no_attribute>
, Attribute, Context, Iterator>
: mpl::true_ {};
template <typename String, bool no_attribute, typename Attribute
, typename Context, typename Iterator>
struct handles_container<qi::no_case_literal_string<String, no_attribute>
, Attribute, Context, Iterator>
: mpl::true_ {};
}}}
#endif
@@ -0,0 +1,431 @@
/*=============================================================================
Copyright (c) 2001-2011 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_SYMBOLS_MARCH_11_2007_1055AM)
#define BOOST_SPIRIT_SYMBOLS_MARCH_11_2007_1055AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/skip_over.hpp>
#include <boost/spirit/home/qi/string/tst.hpp>
#include <boost/spirit/home/qi/reference.hpp>
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/detail/assign_to.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/support/detail/get_encoding.hpp>
#include <boost/spirit/home/support/modify.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/string_traits.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/range.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/shared_ptr.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 Char = char
, typename T = unused_type
, typename Lookup = tst<Char, T>
, typename Filter = tst_pass_through>
struct symbols
: proto::extends<
typename proto::terminal<
reference<symbols<Char, T, Lookup, Filter> >
>::type
, symbols<Char, T, Lookup, Filter>
>
, primitive_parser<symbols<Char, T, Lookup, Filter> >
{
typedef Char char_type; // the character type
typedef T value_type; // the value associated with each entry
typedef symbols<Char, T, Lookup, Filter> this_type;
typedef reference<this_type> reference_;
typedef typename proto::terminal<reference_>::type terminal;
typedef proto::extends<terminal, this_type> base_type;
template <typename Context, typename Iterator>
struct attribute
{
typedef value_type type;
};
symbols(std::string const& name = "symbols")
: base_type(terminal::make(reference_(*this)))
, add(*this)
, remove(*this)
, lookup(new Lookup())
, name_(name)
{
}
symbols(symbols const& syms)
: base_type(terminal::make(reference_(*this)))
, add(*this)
, remove(*this)
, lookup(syms.lookup)
, name_(syms.name_)
{
}
template <typename Filter_>
symbols(symbols<Char, T, Lookup, Filter_> const& syms)
: base_type(terminal::make(reference_(*this)))
, add(*this)
, remove(*this)
, lookup(syms.lookup)
, name_(syms.name_)
{
}
template <typename Symbols>
symbols(Symbols const& syms, std::string const& name = "symbols")
: base_type(terminal::make(reference_(*this)))
, add(*this)
, remove(*this)
, lookup(new Lookup())
, name_(name)
{
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
, std::string const& name = "symbols")
: base_type(terminal::make(reference_(*this)))
, add(*this)
, remove(*this)
, lookup(new Lookup())
, name_(name)
{
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)
{
name_ = rhs.name_;
*lookup = *rhs.lookup;
return *this;
}
template <typename Filter_>
symbols&
operator=(symbols<Char, T, Lookup, Filter_> const& rhs)
{
name_ = rhs.name_;
*lookup = *rhs.lookup;
return *this;
}
void clear()
{
lookup->clear();
}
struct adder;
struct remover;
template <typename Str>
adder const&
operator=(Str const& str)
{
lookup->clear();
return add(str);
}
template <typename Str>
friend adder const&
operator+=(symbols& sym, Str const& str)
{
return sym.add(str);
}
template <typename Str>
friend remover const&
operator-=(symbols& sym, Str const& str)
{
return sym.remove(str);
}
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
// non-const version needed to suppress proto's += kicking in
template <typename Str>
friend adder const&
operator+=(symbols& sym, Str& str)
{
return sym.add(str);
}
// non-const version needed to suppress proto's -= kicking in
template <typename Str>
friend remover const&
operator-=(symbols& sym, Str& str)
{
return sym.remove(str);
}
#else
// for rvalue references
template <typename Str>
friend adder const&
operator+=(symbols& sym, Str&& str)
{
return sym.add(str);
}
// for rvalue references
template <typename Str>
friend remover const&
operator-=(symbols& sym, Str&& str)
{
return sym.remove(str);
}
#endif
template <typename F>
void for_each(F f) const
{
lookup->for_each(f);
}
template <typename Str>
value_type& at(Str const& str)
{
return *lookup->add(traits::get_begin<Char>(str)
, traits::get_end<Char>(str), T());
}
template <typename Iterator>
value_type* prefix_find(Iterator& first, Iterator const& last)
{
return lookup->find(first, last, Filter());
}
template <typename Iterator>
value_type const* prefix_find(Iterator& first, Iterator const& last) const
{
return lookup->find(first, last, Filter());
}
template <typename Str>
value_type* find(Str const& str)
{
return find_impl(traits::get_begin<Char>(str)
, traits::get_end<Char>(str));
}
template <typename Str>
value_type const* find(Str const& str) const
{
return find_impl(traits::get_begin<Char>(str)
, traits::get_end<Char>(str));
}
private:
template <typename Iterator>
value_type* find_impl(Iterator begin, Iterator end)
{
value_type* r = lookup->find(begin, end, Filter());
return begin == end ? r : 0;
}
template <typename Iterator>
value_type const* find_impl(Iterator begin, Iterator end) const
{
value_type const* r = lookup->find(begin, end, Filter());
return begin == end ? r : 0;
}
public:
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);
if (value_type* val_ptr
= lookup->find(first, last, Filter()))
{
spirit::traits::assign_to(*val_ptr, attr_);
return true;
}
return false;
}
template <typename Context>
info what(Context& /*context*/) const
{
return info(name_);
}
void name(std::string const &str)
{
name_ = str;
}
std::string const &name() const
{
return name_;
}
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) const
{
sym.lookup->add(first, last, val);
return *this;
}
template <typename Str>
adder const&
operator()(Str const& s, T const& val = T()) const
{
sym.lookup->add(traits::get_begin<Char>(s)
, traits::get_end<Char>(s), val);
return *this;
}
template <typename Str>
adder const&
operator,(Str const& s) const
{
sym.lookup->add(traits::get_begin<Char>(s)
, traits::get_end<Char>(s), T());
return *this;
}
symbols& sym;
private:
// silence MSVC warning C4512: assignment operator could not be generated
adder& operator= (adder const&);
};
struct remover
{
template <typename, typename = unused_type, typename = unused_type>
struct result { typedef remover 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;
}
template <typename Str>
remover const&
operator()(Str const& s) const
{
sym.lookup->remove(traits::get_begin<Char>(s)
, traits::get_end<Char>(s));
return *this;
}
template <typename Str>
remover const&
operator,(Str const& s) const
{
sym.lookup->remove(traits::get_begin<Char>(s)
, traits::get_end<Char>(s));
return *this;
}
symbols& sym;
private:
// silence MSVC warning C4512: assignment operator could not be generated
remover& operator= (remover const&);
};
adder add;
remover remove;
shared_ptr<Lookup> lookup;
std::string name_;
};
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Char, typename T, typename Lookup
, typename Filter, typename Modifiers>
struct make_primitive<reference<symbols<Char, T, Lookup, Filter> >, Modifiers>
{
template <typename CharEncoding>
struct no_case_filter
{
Char operator()(Char ch) const
{
return static_cast<Char>(CharEncoding::tolower(ch));
}
};
typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
typedef reference<symbols<Char, T, Lookup, Filter> > reference_;
typedef no_case_filter<
typename spirit::detail::get_encoding_with_case<
Modifiers
, char_encoding::standard
, no_case::value>::type>
nc_filter;
typedef typename mpl::if_<
no_case
, symbols<Char, T, Lookup, nc_filter>
, reference_>::type
result_type;
result_type operator()(reference_ ref, unused_type) const
{
return result_type(ref.ref.get());
}
};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Char, typename T, typename Lookup, typename Filter
, typename Attr, typename Context, typename Iterator>
struct handles_container<qi::symbols<Char, T, Lookup, Filter>, Attr, Context, Iterator>
: traits::is_container<Attr> {};
}}}
#if defined(BOOST_MSVC)
# pragma warning(pop)
#endif
#endif
@@ -0,0 +1,137 @@
/*=============================================================================
Copyright (c) 2001-2011 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
#if defined(_MSC_VER)
#pragma once
#endif
#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>
T* 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
@@ -0,0 +1,219 @@
/*=============================================================================
Copyright (c) 2001-2011 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
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/string/tst.hpp>
#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
{
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())
{
if (T* p = node::find(i->second.root, first, last, filter))
{
return p;
}
if (i->second.data)
{
return i->second.data;
}
}
first = save;
}
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) ? true : false;
}
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