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,331 @@
// 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_KARMA_LIT_FEB_22_2007_0534PM)
#define BOOST_SPIRIT_KARMA_LIT_FEB_22_2007_0534PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/string_traits.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/char_class.hpp>
#include <boost/spirit/home/support/container.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/spirit/home/support/detail/get_encoding.hpp>
#include <boost/spirit/home/karma/domain.hpp>
#include <boost/spirit/home/karma/meta_compiler.hpp>
#include <boost/spirit/home/karma/delimit_out.hpp>
#include <boost/spirit/home/karma/auxiliary/lazy.hpp>
#include <boost/spirit/home/karma/detail/get_casetag.hpp>
#include <boost/spirit/home/karma/detail/extract_from.hpp>
#include <boost/spirit/home/karma/detail/string_generate.hpp>
#include <boost/spirit/home/karma/detail/string_compare.hpp>
#include <boost/spirit/home/karma/detail/enable_lit.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/cons.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/utility/enable_if.hpp>
#include <string>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <typename CharEncoding>
struct use_terminal<karma::domain
, tag::char_code<tag::string, CharEncoding> > // enables string
: mpl::true_ {};
template <typename T>
struct use_terminal<karma::domain, T
, typename enable_if<traits::is_string<T> >::type> // enables string literals
: mpl::true_ {};
template <typename CharEncoding, typename A0>
struct use_terminal<karma::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<
karma::domain
, tag::char_code<tag::string, CharEncoding>
, 1 /*arity*/
> : mpl::true_ {};
// enables lit(str)
template <typename A0>
struct use_terminal<karma::domain
, terminal_ex<tag::lit, fusion::vector1<A0> >
, typename enable_if<traits::is_string<A0> >::type>
: mpl::true_ {};
}}
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace karma
{
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::lit;
#endif
using spirit::lit_type;
///////////////////////////////////////////////////////////////////////////
// generate literal strings from a given parameter
///////////////////////////////////////////////////////////////////////////
template <typename CharEncoding, typename Tag>
struct any_string
: primitive_generator<any_string<CharEncoding, Tag> >
{
typedef typename CharEncoding::char_type char_type;
typedef CharEncoding char_encoding;
template <typename Context, typename Unused = unused_type>
struct attribute
{
typedef std::basic_string<char_type> type;
};
// lit has an attached attribute
template <typename OutputIterator, typename Context, typename Delimiter
, typename Attribute>
static bool
generate(OutputIterator& sink, Context& context, Delimiter const& d,
Attribute const& attr)
{
if (!traits::has_optional_value(attr))
return false;
typedef typename attribute<Context>::type attribute_type;
return
karma::detail::string_generate(sink
, traits::extract_from<attribute_type>(attr, context)
, char_encoding(), Tag()) &&
karma::delimit_out(sink, d); // always do post-delimiting
}
// this lit has no attribute attached, it needs to have been
// initialized from a direct literal
template <typename OutputIterator, typename Context, typename Delimiter>
static bool generate(OutputIterator&, Context&, Delimiter const&,
unused_type const&)
{
// It is not possible (doesn't make sense) to use string without
// providing any attribute, as the generator doesn't 'know' what
// character to output. The following assertion fires if this
// situation is detected in your code.
BOOST_SPIRIT_ASSERT_FAIL(OutputIterator, string_not_usable_without_attribute, ());
return false;
}
template <typename Context>
static info what(Context const& /*context*/)
{
return info("any-string");
}
};
///////////////////////////////////////////////////////////////////////////
// generate literal strings
///////////////////////////////////////////////////////////////////////////
template <typename String, typename CharEncoding, typename Tag, bool no_attribute>
struct literal_string
: primitive_generator<literal_string<String, CharEncoding, Tag, no_attribute> >
{
typedef CharEncoding char_encoding;
typedef typename
remove_const<typename traits::char_type_of<String>::type>::type
char_type;
typedef std::basic_string<char_type> string_type;
template <typename Context, typename Unused = unused_type>
struct attribute
: mpl::if_c<no_attribute, unused_type, string_type>
{};
literal_string(typename add_reference<String>::type str)
: str_(str)
{}
// A string("...") which additionally has an associated attribute emits
// its immediate literal only if it matches the attribute, otherwise
// it fails.
template <
typename OutputIterator, typename Context, typename Delimiter
, typename Attribute>
bool generate(OutputIterator& sink, Context& context
, Delimiter const& d, Attribute const& attr) const
{
if (!traits::has_optional_value(attr))
return false;
// fail if attribute isn't matched by immediate literal
typedef typename attribute<Context>::type attribute_type;
using spirit::traits::get_c_string;
if (!detail::string_compare(
get_c_string(
traits::extract_from<attribute_type>(attr, context))
, get_c_string(str_), char_encoding(), Tag()))
{
return false;
}
return detail::string_generate(sink, str_, char_encoding(), Tag()) &&
karma::delimit_out(sink, d); // always do post-delimiting
}
// A string("...") without any associated attribute just emits its
// immediate literal
template <typename OutputIterator, typename Context, typename Delimiter>
bool generate(OutputIterator& sink, Context&, Delimiter const& d
, unused_type) const
{
return detail::string_generate(sink, str_, char_encoding(), Tag()) &&
karma::delimit_out(sink, d); // always do post-delimiting
}
template <typename Context>
info what(Context const& /*context*/) const
{
return info("literal-string", str_);
}
string_type str_;
};
///////////////////////////////////////////////////////////////////////////
// Generator generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
// string
template <typename CharEncoding, typename Modifiers>
struct make_primitive<
tag::char_code<tag::string, CharEncoding>
, Modifiers>
{
static bool const lower =
has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
static bool const upper =
has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
typedef any_string<
typename spirit::detail::get_encoding_with_case<
Modifiers, CharEncoding, lower || upper>::type
, typename detail::get_casetag<Modifiers, lower || upper>::type
> result_type;
result_type operator()(unused_type, unused_type) const
{
return result_type();
}
};
// string literal
template <typename T, typename Modifiers>
struct make_primitive<T, Modifiers
, typename enable_if<traits::is_string<T> >::type>
{
static bool const lower =
has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
static bool const upper =
has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
typedef typename add_const<T>::type const_string;
typedef literal_string<
const_string
, typename spirit::detail::get_encoding_with_case<
Modifiers, unused_type, lower || upper>::type
, typename detail::get_casetag<Modifiers, lower || upper>::type
, true
> result_type;
result_type operator()(
typename add_reference<const_string>::type str, unused_type) const
{
return result_type(str);
}
};
///////////////////////////////////////////////////////////////////////////
namespace detail
{
template <typename CharEncoding, typename Modifiers, typename A0
, bool no_attribute>
struct make_string_direct
{
static bool const lower =
has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
static bool const upper =
has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
typedef typename add_const<A0>::type const_string;
typedef literal_string<
const_string
, typename spirit::detail::get_encoding_with_case<
Modifiers, unused_type, lower || upper>::type
, typename detail::get_casetag<Modifiers, lower || upper>::type
, no_attribute
> result_type;
template <typename Terminal>
result_type operator()(Terminal const& term, unused_type) const
{
return result_type(fusion::at_c<0>(term.args));
}
};
}
// string("..."), lit("...")
template <typename CharEncoding, typename Modifiers, typename A0>
struct make_primitive<
terminal_ex<
tag::char_code<tag::string, CharEncoding>
, fusion::vector1<A0> >
, Modifiers>
: detail::make_string_direct<CharEncoding, Modifiers, A0, false>
{};
template <typename Modifiers, typename A0>
struct make_primitive<
terminal_ex<tag::lit, fusion::vector1<A0> >
, Modifiers
, typename enable_if<traits::is_string<A0> >::type>
: detail::make_string_direct<
typename traits::char_encoding_from_char<
typename traits::char_type_of<A0>::type>::type
, Modifiers, A0, true>
{};
}}} // namespace boost::spirit::karma
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename CharEncoding, typename Tag, typename Attribute
, typename Context, typename Iterator>
struct handles_container<karma::any_string<CharEncoding, Tag>, Attribute
, Context, Iterator>
: mpl::false_ {};
template <typename String, typename CharEncoding, typename Tag
, bool no_attribute, typename Attribute, typename Context
, typename Iterator>
struct handles_container<karma::literal_string<String, CharEncoding, Tag
, no_attribute>, Attribute, Context, Iterator>
: mpl::false_ {};
}}}
#endif
@@ -0,0 +1,768 @@
// Copyright (c) 2001-2011 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(BOOST_SPIRIT_KARMA_SYMBOLS_NOV_23_2009_1251PM)
#define BOOST_SPIRIT_KARMA_SYMBOLS_NOV_23_2009_1251PM
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/attributes_fwd.hpp>
#include <boost/spirit/home/support/detail/get_encoding.hpp>
#include <boost/spirit/home/karma/detail/attributes.hpp>
#include <boost/spirit/home/karma/detail/extract_from.hpp>
#include <boost/spirit/home/karma/domain.hpp>
#include <boost/spirit/home/karma/meta_compiler.hpp>
#include <boost/spirit/home/karma/reference.hpp>
#include <boost/spirit/home/karma/generate.hpp>
#include <boost/spirit/home/karma/delimit_out.hpp>
#include <boost/spirit/home/karma/detail/get_casetag.hpp>
#include <boost/spirit/home/karma/detail/string_generate.hpp>
#include <boost/config.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/mpl/if.hpp>
#include <map>
#include <set>
#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 traits
{
template <typename T, typename Attribute, typename Enable>
struct symbols_lookup
{
typedef
mpl::eval_if<fusion::traits::is_sequence<T>
, traits::detail::value_at_c<T, 0>
, detail::add_const_ref<T> > sequence_type;
typedef typename
mpl::eval_if<traits::is_container<T>
, traits::container_value<T>
, sequence_type>::type type;
// fusion sequence
template <typename T_>
static type call(T_ const& t, mpl::false_, mpl::true_)
{
return fusion::at_c<0>(t);
}
// container
template <typename T_, typename IsSequence>
static type call(T_ const& t, mpl::true_, IsSequence)
{
return t[0];
}
// not a container and not a fusion sequence
template <typename T_>
static type call(T_ const& t, mpl::false_, mpl::false_)
{
return t;
}
static type call(T const& t)
{
typedef typename traits::is_container<T>::type is_container;
typedef typename fusion::traits::is_sequence<T>::type is_sequence;
return call(t, is_container(), is_sequence());
}
};
template <typename Attribute>
struct symbols_lookup<Attribute, Attribute>
{
typedef Attribute const& type;
static type call(Attribute const& t)
{
return t;
}
};
template <typename Attribute, typename T, typename Enable>
struct symbols_value
{
typedef
mpl::eval_if<fusion::traits::is_sequence<T>
, traits::detail::value_at_c<T, 1>
, mpl::identity<unused_type> > sequence_type;
typedef typename
mpl::eval_if<traits::is_container<T>
, traits::container_value<T>
, sequence_type>::type type;
// fusion sequence
template <typename T_>
static type call(T_ const& t, mpl::false_, mpl::true_)
{
return fusion::at_c<1>(t);
}
// container
template <typename T_, typename IsSequence>
static type call(T_ const& t, mpl::true_, IsSequence)
{
return t[1];
}
// not a container nor a fusion sequence
template <typename T_>
static type call(T_ const&, mpl::false_, mpl::false_)
{
return unused;
}
static type call(T const& t)
{
typedef typename traits::is_container<T>::type is_container;
typedef typename fusion::traits::is_sequence<T>::type is_sequence;
return call(t, is_container(), is_sequence());
}
};
template <typename Attribute>
struct symbols_value<Attribute, Attribute>
{
typedef unused_type type;
static type call(Attribute const&)
{
return unused;
}
};
}}}
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace karma
{
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Attribute>
struct symbols_lookup
: mpl::if_<
traits::not_is_unused<T>
, std::map<Attribute, T>
, std::set<Attribute>
>
{};
///////////////////////////////////////////////////////////////////////////
namespace detail
{
///////////////////////////////////////////////////////////////////////
template <typename CharEncoding, typename Tag>
struct generate_encoded
{
typedef typename
proto::terminal<tag::char_code<Tag, CharEncoding> >::type
encoding_type;
template <typename OutputIterator, typename Expr, typename Attribute>
static bool call(OutputIterator& sink, Expr const& expr
, Attribute const& attr)
{
encoding_type const encoding = encoding_type();
return karma::generate(sink, encoding[expr], attr);
}
};
template <>
struct generate_encoded<unused_type, unused_type>
{
template <typename OutputIterator, typename Expr, typename Attribute>
static bool call(OutputIterator& sink, Expr const& expr
, Attribute const& attr)
{
return karma::generate(sink, expr, attr);
}
};
}
template <
typename Attribute = char, typename T = unused_type
, typename Lookup = typename symbols_lookup<T, Attribute>::type
, typename CharEncoding = unused_type, typename Tag = unused_type>
struct symbols
: proto::extends<
typename proto::terminal<
reference<symbols<Attribute, T, Lookup, CharEncoding, Tag> >
>::type
, symbols<Attribute, T, Lookup, CharEncoding, Tag> >
, primitive_generator<
symbols<Attribute, T, Lookup, CharEncoding, Tag> >
{
typedef T value_type; // the value associated with each entry
typedef reference<symbols> reference_;
typedef typename proto::terminal<reference_>::type terminal;
typedef proto::extends<terminal, symbols> base_type;
template <typename Context, typename Unused>
struct attribute
{
typedef Attribute 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 CharEncoding_, typename Tag_>
symbols(symbols<Attribute, T, Lookup, CharEncoding_, Tag_> const& syms)
: base_type(terminal::make(reference_(*this)))
, add(*this)
, remove(*this)
, lookup(syms.lookup)
, name_(syms.name_)
{}
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)
{
*lookup = *rhs.lookup;
name_ = rhs.name_;
return *this;
}
template <typename CharEncoding_, typename Tag_>
symbols&
operator=(symbols<Attribute, T, Lookup, CharEncoding_, Tag_> const& rhs)
{
*lookup = *rhs.lookup;
name_ = rhs.name_;
return *this;
}
void clear()
{
lookup->clear();
}
struct adder;
struct remover;
template <typename Attr, typename T_>
adder const&
operator=(std::pair<Attr, T_> const& p)
{
lookup->clear();
return add(p.first, p.second);
}
template <typename Attr, typename T_>
friend adder const&
operator+= (symbols& sym, std::pair<Attr, T_> const& p)
{
return sym.add(p.first, p.second);
}
template <typename Attr>
friend remover const&
operator-= (symbols& sym, Attr const& attr)
{
return sym.remove(attr);
}
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
// non-const version needed to suppress proto's += kicking in
template <typename Attr, typename T_>
friend adder const&
operator+= (symbols& sym, std::pair<Attr, T_>& p)
{
return sym.add(p.first, p.second);
}
// non-const version needed to suppress proto's -= kicking in
template <typename Attr>
friend remover const&
operator-= (symbols& sym, Attr& attr)
{
return sym.remove(attr);
}
#else
// for rvalue references
template <typename Attr, typename T_>
friend adder const&
operator+= (symbols& sym, std::pair<Attr, T_>&& p)
{
return sym.add(p.first, p.second);
}
// for rvalue references
template <typename Attr>
friend remover const&
operator-= (symbols& sym, Attr&& attr)
{
return sym.remove(attr);
}
#endif
template <typename F>
void for_each(F f) const
{
std::for_each(lookup->begin(), lookup->end(), f);
}
template <typename Attr>
value_type* find(Attr const& attr)
{
typename Lookup::iterator it = lookup->find(attr);
return (it != lookup->end()) ? &(*it).second : 0;
}
template <typename Attr>
value_type& at(Attr const& attr)
{
return (*lookup)[attr];
}
///////////////////////////////////////////////////////////////////////
template <typename OutputIterator, typename Context, typename Delimiter
, typename Attr>
bool generate(OutputIterator& sink, Context&, Delimiter const& d
, Attr const& attr) const
{
typename Lookup::iterator it = lookup->find(
traits::symbols_lookup<Attr, Attribute>::call(attr));
if (it == lookup->end())
return false;
return karma::detail::generate_encoded<CharEncoding, Tag>::call(
sink, (*it).second
, traits::symbols_value<Attribute, Attr>::call(attr)) &&
karma::delimit_out(sink, d);
}
template <typename Context>
info what(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>
struct result { typedef adder const& type; };
adder(symbols& sym)
: sym(sym)
{
}
template <typename Attr>
adder const&
operator()(Attr const& attr, T const& val = T()) const
{
sym.lookup->insert(typename Lookup::value_type(attr, val));
return *this;
}
template <typename Attr>
adder const&
operator, (Attr const& attr) const
{
sym.lookup->insert(typename Lookup::value_type(attr, T()));
return *this;
}
symbols& sym;
private:
// silence MSVC warning C4512: assignment operator could not be generated
adder& operator= (adder const&);
};
struct remover
{
template <typename>
struct result { typedef remover const& type; };
remover(symbols& sym)
: sym(sym)
{
}
template <typename Attr>
remover const&
operator()(Attr const& attr) const
{
sym.lookup->erase(attr);
return *this;
}
template <typename Attr>
remover const&
operator, (Attr const& attr) const
{
sym.lookup->erase(attr);
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_;
};
///////////////////////////////////////////////////////////////////////////
// specialization for unused stored type
template <
typename Attribute, typename Lookup
, typename CharEncoding, typename Tag>
struct symbols<Attribute, unused_type, Lookup, CharEncoding, Tag>
: proto::extends<
typename proto::terminal<
spirit::karma::reference<
symbols<Attribute, unused_type, Lookup, CharEncoding, Tag> >
>::type
, symbols<Attribute, unused_type, Lookup, CharEncoding, Tag>
>
, spirit::karma::generator<
symbols<Attribute, unused_type, Lookup, CharEncoding, Tag> >
{
typedef unused_type value_type; // the value associated with each entry
typedef spirit::karma::reference<symbols> reference_;
typedef typename proto::terminal<reference_>::type terminal;
typedef proto::extends<terminal, symbols> base_type;
template <typename Context, typename Unused>
struct attribute
{
typedef Attribute 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 CharEncoding_, typename Tag_>
symbols(symbols<Attribute, unused_type, Lookup, CharEncoding_, Tag_> const& syms)
: base_type(terminal::make(reference_(*this)))
, add(*this)
, remove(*this)
, lookup(syms.lookup)
, name_(syms.name_)
{}
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)
{
*lookup = *rhs.lookup;
name_ = rhs.name_;
return *this;
}
template <typename CharEncoding_, typename Tag_>
symbols&
operator=(symbols<Attribute, unused_type, Lookup, CharEncoding_, Tag_> const& rhs)
{
*lookup = *rhs.lookup;
name_ = rhs.name_;
return *this;
}
void clear()
{
lookup->clear();
}
struct adder;
struct remover;
template <typename Attr>
adder const&
operator=(Attr const& attr)
{
lookup->clear();
return add(attr);
}
template <typename Attr>
friend adder const&
operator+= (symbols& sym, Attr const& attr)
{
return sym.add(attr);
}
template <typename Attr>
friend remover const&
operator-= (symbols& sym, Attr const& attr)
{
return sym.remove(attr);
}
// non-const version needed to suppress proto's += kicking in
template <typename Attr>
friend adder const&
operator+= (symbols& sym, Attr& attr)
{
return sym.add(attr);
}
// non-const version needed to suppress proto's -= kicking in
template <typename Attr>
friend remover const&
operator-= (symbols& sym, Attr& attr)
{
return sym.remove(attr);
}
template <typename F>
void for_each(F f) const
{
std::for_each(lookup->begin(), lookup->end(), f);
}
template <typename Attr>
value_type const* find(Attr const& attr)
{
typename Lookup::iterator it = lookup->find(attr);
return (it != lookup->end()) ? &unused : 0;
}
template <typename Attr>
value_type at(Attr const& attr)
{
typename Lookup::iterator it = lookup->find(attr);
if (it == lookup->end())
add(attr);
return unused;
}
///////////////////////////////////////////////////////////////////////
template <typename OutputIterator, typename Context, typename Delimiter
, typename Attr>
bool generate(OutputIterator& sink, Context&, Delimiter const& d
, Attr const& attr) const
{
typename Lookup::iterator it = lookup->find(
traits::symbols_lookup<Attr, Attribute>::call(attr));
if (it == lookup->end())
return false;
return karma::detail::generate_encoded<CharEncoding, Tag>::
call(sink
, traits::symbols_lookup<Attr, Attribute>::call(attr)
, unused) &&
karma::delimit_out(sink, d);
}
template <typename Context>
info what(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>
struct result { typedef adder const& type; };
adder(symbols& sym)
: sym(sym)
{
}
template <typename Attr>
adder const&
operator()(Attr const& attr) const
{
sym.lookup->insert(attr);
return *this;
}
template <typename Attr>
adder const&
operator, (Attr const& attr) const
{
sym.lookup->insert(attr);
return *this;
}
symbols& sym;
private:
// silence MSVC warning C4512: assignment operator could not be generated
adder& operator= (adder const&);
};
struct remover
{
template <typename>
struct result { typedef remover const& type; };
remover(symbols& sym)
: sym(sym)
{
}
template <typename Attr>
remover const&
operator()(Attr const& attr) const
{
sym.lookup->erase(attr);
return *this;
}
template <typename Attr>
remover const&
operator, (Attr const& attr) const
{
sym.lookup->erase(attr);
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_;
};
///////////////////////////////////////////////////////////////////////////
// Generator generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Attribute, typename T, typename Lookup
, typename CharEnconding, typename Tag, typename Modifiers>
struct make_primitive<
reference<symbols<Attribute, T, Lookup, CharEnconding, Tag> >
, Modifiers>
{
static bool const lower =
has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
static bool const upper =
has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
typedef reference<
symbols<Attribute, T, Lookup, CharEnconding, Tag>
> reference_;
typedef typename mpl::if_c<
lower || upper
, symbols<
Attribute, T, Lookup
, typename spirit::detail::get_encoding_with_case<
Modifiers, unused_type, lower || upper>::type
, typename detail::get_casetag<Modifiers, lower || upper>::type>
, 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 Attribute, typename T, typename Lookup
, typename CharEncoding, typename Tag
, typename Attr, typename Context, typename Iterator>
struct handles_container<karma::symbols<Attribute, T, Lookup, CharEncoding, Tag>
, Attr, Context, Iterator>
: traits::is_container<Attr> {};
}}}
#if defined(BOOST_MSVC)
# pragma warning(pop)
#endif
#endif