stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork
This commit is contained in:
+250
@@ -0,0 +1,250 @@
|
||||
// Copyright (c) 2001-2011 Hartmut Kaiser
|
||||
// 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(SPIRIT_KARMA_ALTERNATIVE_MAR_01_2007_1124AM)
|
||||
#define SPIRIT_KARMA_ALTERNATIVE_MAR_01_2007_1124AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/karma/domain.hpp>
|
||||
#include <boost/spirit/home/karma/directive/buffer.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/support/utree/utree_traits_fwd.hpp>
|
||||
#include <boost/spirit/home/karma/detail/attributes.hpp>
|
||||
#include <boost/spirit/home/support/detail/hold_any.hpp>
|
||||
#include <boost/spirit/home/karma/detail/output_iterator.hpp>
|
||||
#include <boost/spirit/home/support/container.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/variant.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit { namespace karma { namespace detail
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// execute a generator if the given Attribute type is compatible
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// this gets instantiated if the Attribute type is _not_ compatible with
|
||||
// the generator
|
||||
template <typename Component, typename Attribute, typename Expected
|
||||
, typename Enable = void>
|
||||
struct alternative_generate
|
||||
{
|
||||
template <typename OutputIterator, typename Context, typename Delimiter>
|
||||
static bool
|
||||
call(Component const&, OutputIterator&, Context&, Delimiter const&
|
||||
, Attribute const&, bool& failed)
|
||||
{
|
||||
failed = true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Component>
|
||||
struct alternative_generate<Component, unused_type, unused_type>
|
||||
{
|
||||
template <typename OutputIterator, typename Context, typename Delimiter>
|
||||
static bool
|
||||
call(Component const& component, OutputIterator& sink, Context& ctx
|
||||
, Delimiter const& d, unused_type, bool&)
|
||||
{
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
|
||||
component; // suppresses warning: C4100: 'component' : unreferenced formal parameter
|
||||
#endif
|
||||
// return true if any of the generators succeed
|
||||
return component.generate(sink, ctx, d, unused);
|
||||
}
|
||||
};
|
||||
|
||||
// this gets instantiated if there is no Attribute given for the
|
||||
// alternative generator
|
||||
template <typename Component, typename Expected>
|
||||
struct alternative_generate<Component, unused_type, Expected>
|
||||
: alternative_generate<Component, unused_type, unused_type> {};
|
||||
|
||||
// this gets instantiated if the generator does not expect to receive an
|
||||
// Attribute (the generator is self contained).
|
||||
template <typename Component, typename Attribute>
|
||||
struct alternative_generate<Component, Attribute, unused_type>
|
||||
: alternative_generate<Component, unused_type, unused_type> {};
|
||||
|
||||
// this gets instantiated if the Attribute type is compatible to the
|
||||
// generator
|
||||
template <typename Component, typename Attribute, typename Expected>
|
||||
struct alternative_generate<Component, Attribute, Expected
|
||||
, typename enable_if<
|
||||
traits::compute_compatible_component<Expected, Attribute, karma::domain> >::type>
|
||||
{
|
||||
template <typename OutputIterator, typename Context, typename Delimiter>
|
||||
static bool
|
||||
call(Component const& component, OutputIterator& sink
|
||||
, Context& ctx, Delimiter const& d, Attribute const& attr, bool&)
|
||||
{
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
|
||||
component; // suppresses warning: C4100: 'component' : unreferenced formal parameter
|
||||
#endif
|
||||
return call(component, sink, ctx, d, attr
|
||||
, spirit::traits::not_is_variant<Attribute, karma::domain>());
|
||||
}
|
||||
|
||||
template <typename OutputIterator, typename Context, typename Delimiter>
|
||||
static bool
|
||||
call(Component const& component, OutputIterator& sink
|
||||
, Context& ctx, Delimiter const& d, Attribute const& attr, mpl::true_)
|
||||
{
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
|
||||
component; // suppresses warning: C4100: 'component' : unreferenced formal parameter
|
||||
#endif
|
||||
return component.generate(sink, ctx, d, attr);
|
||||
}
|
||||
|
||||
template <typename OutputIterator, typename Context, typename Delimiter>
|
||||
static bool
|
||||
call(Component const& component, OutputIterator& sink
|
||||
, Context& ctx, Delimiter const& d, Attribute const& attr, mpl::false_)
|
||||
{
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
|
||||
component; // suppresses warning: C4100: 'component' : unreferenced formal parameter
|
||||
#endif
|
||||
typedef
|
||||
traits::compute_compatible_component<Expected, Attribute, domain>
|
||||
component_type;
|
||||
|
||||
// if we got passed an empty optional, just fail generation
|
||||
if (!traits::has_optional_value(attr))
|
||||
return false;
|
||||
|
||||
// make sure, the content of the passed variant matches our
|
||||
// expectations
|
||||
typename traits::optional_attribute<Attribute>::type attr_ =
|
||||
traits::optional_value(attr);
|
||||
if (!component_type::is_compatible(spirit::traits::which(attr_)))
|
||||
return false;
|
||||
|
||||
// returns true if any of the generators succeed
|
||||
typedef typename component_type::compatible_type compatible_type;
|
||||
return component.generate(sink, ctx, d
|
||||
, boost::get<compatible_type>(attr_));
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// alternative_generate_function: a functor supplied to fusion::any which
|
||||
// will be executed for every generator in a given alternative generator
|
||||
// expression
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename OutputIterator, typename Context, typename Delimiter,
|
||||
typename Attribute, typename Strict>
|
||||
struct alternative_generate_function
|
||||
{
|
||||
alternative_generate_function(OutputIterator& sink_, Context& ctx_
|
||||
, Delimiter const& d, Attribute const& attr_)
|
||||
: sink(sink_), ctx(ctx_), delim(d), attr(attr_) {}
|
||||
|
||||
template <typename Component>
|
||||
bool operator()(Component const& component)
|
||||
{
|
||||
typedef
|
||||
typename traits::attribute_of<Component, Context>::type
|
||||
expected_type;
|
||||
typedef
|
||||
alternative_generate<Component, Attribute, expected_type>
|
||||
generate;
|
||||
|
||||
// wrap the given output iterator avoid output as long as one
|
||||
// component fails
|
||||
detail::enable_buffering<OutputIterator> buffering(sink);
|
||||
bool r = false;
|
||||
bool failed = false; // will be ignored
|
||||
{
|
||||
detail::disable_counting<OutputIterator> nocounting(sink);
|
||||
r = generate::call(component, sink, ctx, delim, attr, failed);
|
||||
}
|
||||
if (r)
|
||||
buffering.buffer_copy();
|
||||
return r;
|
||||
}
|
||||
|
||||
// avoid double buffering
|
||||
template <typename Component>
|
||||
bool operator()(buffer_directive<Component> const& component)
|
||||
{
|
||||
typedef typename
|
||||
traits::attribute_of<Component, Context>::type
|
||||
expected_type;
|
||||
typedef alternative_generate<
|
||||
buffer_directive<Component>, Attribute, expected_type>
|
||||
generate;
|
||||
|
||||
bool failed = false; // will be ignored
|
||||
return generate::call(component, sink, ctx, delim, attr, failed);
|
||||
}
|
||||
|
||||
OutputIterator& sink;
|
||||
Context& ctx;
|
||||
Delimiter const& delim;
|
||||
Attribute const& attr;
|
||||
|
||||
private:
|
||||
// silence MSVC warning C4512: assignment operator could not be generated
|
||||
alternative_generate_function& operator= (alternative_generate_function const&);
|
||||
};
|
||||
|
||||
// specialization for strict alternatives
|
||||
template <typename OutputIterator, typename Context, typename Delimiter,
|
||||
typename Attribute>
|
||||
struct alternative_generate_function<
|
||||
OutputIterator, Context, Delimiter, Attribute, mpl::true_>
|
||||
{
|
||||
alternative_generate_function(OutputIterator& sink_, Context& ctx_
|
||||
, Delimiter const& d, Attribute const& attr_)
|
||||
: sink(sink_), ctx(ctx_), delim(d), attr(attr_), failed(false) {}
|
||||
|
||||
template <typename Component>
|
||||
bool operator()(Component const& component)
|
||||
{
|
||||
typedef
|
||||
typename traits::attribute_of<Component, Context>::type
|
||||
expected_type;
|
||||
typedef
|
||||
alternative_generate<Component, Attribute, expected_type>
|
||||
generate;
|
||||
|
||||
if (failed)
|
||||
return false; // give up when already failed
|
||||
|
||||
// wrap the given output iterator avoid output as long as one
|
||||
// component fails
|
||||
detail::enable_buffering<OutputIterator> buffering(sink);
|
||||
bool r = false;
|
||||
{
|
||||
detail::disable_counting<OutputIterator> nocounting(sink);
|
||||
r = generate::call(component, sink, ctx, delim, attr, failed);
|
||||
}
|
||||
if (r && !failed)
|
||||
{
|
||||
buffering.buffer_copy();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
OutputIterator& sink;
|
||||
Context& ctx;
|
||||
Delimiter const& delim;
|
||||
Attribute const& attr;
|
||||
bool failed;
|
||||
|
||||
private:
|
||||
// silence MSVC warning C4512: assignment operator could not be generated
|
||||
alternative_generate_function& operator= (alternative_generate_function const&);
|
||||
};
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,74 @@
|
||||
// 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_AS_STRING_DEC_18_0644PM)
|
||||
#define BOOST_SPIRIT_KARMA_AS_STRING_DEC_18_0644PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/support/attributes_fwd.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// This file contains the attribute to string conversion utility. The
|
||||
// utility provided also accept spirit's unused_type; all no-ops. Compiler
|
||||
// optimization will easily strip these away.
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename Attribute>
|
||||
inline typename spirit::result_of::attribute_as<T, Attribute>::type
|
||||
as(Attribute const& attr)
|
||||
{
|
||||
return attribute_as<T, Attribute>::call(attr);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline unused_type as(unused_type)
|
||||
{
|
||||
return unused;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename Attribute>
|
||||
inline bool valid_as(Attribute const& attr)
|
||||
{
|
||||
return attribute_as<T, Attribute>::is_valid(attr);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool valid_as(unused_type)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}}}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit { namespace result_of
|
||||
{
|
||||
template <typename T, typename Attribute>
|
||||
struct attribute_as
|
||||
: traits::attribute_as<T, Attribute>
|
||||
{};
|
||||
|
||||
template <typename T>
|
||||
struct attribute_as<T, unused_type>
|
||||
{
|
||||
typedef unused_type type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct attribute_as<T, unused_type const>
|
||||
{
|
||||
typedef unused_type type;
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,108 @@
|
||||
// Copyright (c) 2001-2011 Hartmut Kaiser
|
||||
// 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(SPIRIT_KARMA_DETAIL_ATTRIBUTES_APR_18_2010_0453PM)
|
||||
#define SPIRIT_KARMA_DETAIL_ATTRIBUTES_APR_18_2010_0453PM
|
||||
|
||||
#include <boost/spirit/home/karma/domain.hpp>
|
||||
#include <boost/spirit/home/support/attributes_fwd.hpp>
|
||||
#include <boost/spirit/home/support/attributes.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit { namespace karma
|
||||
{
|
||||
template <typename Exposed, typename Transformed, typename Enable = void>
|
||||
struct transform_attribute
|
||||
{
|
||||
typedef Transformed type;
|
||||
static Transformed pre(Exposed& val)
|
||||
{
|
||||
return Transformed(traits::extract_from<Transformed>(val, unused));
|
||||
}
|
||||
// Karma only, no post() and no fail() required
|
||||
};
|
||||
|
||||
template <typename Exposed, typename Transformed>
|
||||
struct transform_attribute<boost::optional<Exposed> const, Transformed
|
||||
, typename disable_if<is_same<boost::optional<Exposed>, Transformed> >::type>
|
||||
{
|
||||
typedef Transformed const& type;
|
||||
static Transformed const& pre(boost::optional<Exposed> const& val)
|
||||
{
|
||||
return boost::get<Transformed>(val);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Attribute>
|
||||
struct transform_attribute<Attribute const, Attribute>
|
||||
{
|
||||
typedef Attribute const& type;
|
||||
static Attribute const& pre(Attribute const& val) { return val; }
|
||||
// Karma only, no post() and no fail() required
|
||||
};
|
||||
|
||||
// reference types need special handling
|
||||
template <typename Exposed, typename Transformed>
|
||||
struct transform_attribute<Exposed&, Transformed>
|
||||
: transform_attribute<Exposed, Transformed>
|
||||
{};
|
||||
|
||||
template <typename Exposed, typename Transformed>
|
||||
struct transform_attribute<Exposed const&, Transformed>
|
||||
: transform_attribute<Exposed const, Transformed>
|
||||
{};
|
||||
|
||||
template <typename Attribute>
|
||||
struct transform_attribute<Attribute const&, Attribute>
|
||||
: transform_attribute<Attribute const, Attribute>
|
||||
{};
|
||||
|
||||
// unused_type needs some special handling as well
|
||||
template <>
|
||||
struct transform_attribute<unused_type, unused_type>
|
||||
{
|
||||
typedef unused_type type;
|
||||
static unused_type pre(unused_type) { return unused; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct transform_attribute<unused_type const, unused_type>
|
||||
: transform_attribute<unused_type, unused_type>
|
||||
{};
|
||||
|
||||
template <typename Attribute>
|
||||
struct transform_attribute<unused_type, Attribute>
|
||||
: transform_attribute<unused_type, unused_type>
|
||||
{};
|
||||
|
||||
template <typename Attribute>
|
||||
struct transform_attribute<unused_type const, Attribute>
|
||||
: transform_attribute<unused_type, unused_type>
|
||||
{};
|
||||
|
||||
template <typename Attribute>
|
||||
struct transform_attribute<Attribute, unused_type>
|
||||
: transform_attribute<unused_type, unused_type>
|
||||
{};
|
||||
|
||||
template <typename Attribute>
|
||||
struct transform_attribute<Attribute const, unused_type>
|
||||
: transform_attribute<unused_type, unused_type>
|
||||
{};
|
||||
}}}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
template <typename Exposed, typename Transformed>
|
||||
struct transform_attribute<Exposed, Transformed, karma::domain>
|
||||
: karma::transform_attribute<Exposed, Transformed>
|
||||
{};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
// 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_DEFAULT_WIDTH_APR_07_2009_0912PM)
|
||||
#define BOOST_SPIRIT_KARMA_DEFAULT_WIDTH_APR_07_2009_0912PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The BOOST_KARMA_DEFAULT_FIELD_LENGTH specifies the default field length
|
||||
// to be used for padding.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(BOOST_KARMA_DEFAULT_FIELD_LENGTH)
|
||||
#define BOOST_KARMA_DEFAULT_FIELD_LENGTH 10
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The BOOST_KARMA_DEFAULT_FIELD_MAXWIDTH specifies the default maximal field
|
||||
// length to be used for the maxwidth directive.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(BOOST_KARMA_DEFAULT_FIELD_MAXWIDTH)
|
||||
#define BOOST_KARMA_DEFAULT_FIELD_MAXWIDTH 10
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The BOOST_KARMA_DEFAULT_COLUMNS specifies the default number of columns to
|
||||
// be used with the columns directive.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(BOOST_KARMA_DEFAULT_COLUMNS)
|
||||
#define BOOST_KARMA_DEFAULT_COLUMNS 5
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit { namespace karma { namespace detail
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct default_width
|
||||
{
|
||||
operator int() const
|
||||
{
|
||||
return BOOST_KARMA_DEFAULT_FIELD_LENGTH;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct default_max_width
|
||||
{
|
||||
operator int() const
|
||||
{
|
||||
return BOOST_KARMA_DEFAULT_FIELD_MAXWIDTH;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct default_columns
|
||||
{
|
||||
operator int() const
|
||||
{
|
||||
return BOOST_KARMA_DEFAULT_COLUMNS;
|
||||
}
|
||||
};
|
||||
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,30 @@
|
||||
// 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_DETAIL_ENABLE_LIT_JAN_06_2011_1009PM)
|
||||
#define BOOST_SPIRIT_KARMA_DETAIL_ENABLE_LIT_JAN_06_2011_1009PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/karma/domain.hpp>
|
||||
#include <boost/spirit/home/karma/generator.hpp>
|
||||
#include <boost/spirit/home/karma/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/karma/auxiliary/lazy.hpp>
|
||||
#include <boost/fusion/include/vector.hpp>
|
||||
#include <boost/spirit/home/support/string_traits.hpp>
|
||||
#include <boost/spirit/home/support/common_terminals.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
// enables lazy lit(...) for karma
|
||||
template <>
|
||||
struct use_lazy_terminal<karma::domain, tag::lit, 1>
|
||||
: mpl::true_ {};
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,274 @@
|
||||
// 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_EXTRACT_FROM_SEP_30_2009_0732AM)
|
||||
#define BOOST_SPIRIT_KARMA_EXTRACT_FROM_SEP_30_2009_0732AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/include/phoenix_core.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/support/attributes_fwd.hpp>
|
||||
#include <boost/spirit/home/karma/detail/attributes.hpp>
|
||||
#include <boost/spirit/home/support/container.hpp>
|
||||
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// This file contains attribute extraction utilities. The utilities
|
||||
// provided also accept spirit's unused_type; all no-ops. Compiler
|
||||
// optimization will easily strip these away.
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace detail
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// extract first and second element of a fusion sequence
|
||||
template <typename T>
|
||||
struct add_const_ref
|
||||
: add_reference<typename add_const<T>::type>
|
||||
{};
|
||||
|
||||
template <typename T, int N>
|
||||
struct value_at_c
|
||||
: add_const_ref<typename fusion::result_of::value_at_c<T, N>::type>
|
||||
{};
|
||||
}
|
||||
|
||||
// This is the default case: the plain attribute values
|
||||
template <typename Attribute, typename Exposed, typename Enable/*= void*/>
|
||||
struct extract_from_attribute
|
||||
{
|
||||
typedef typename traits::one_element_sequence<Attribute>::type
|
||||
is_one_element_sequence;
|
||||
|
||||
typedef typename mpl::eval_if<
|
||||
is_one_element_sequence
|
||||
, detail::value_at_c<Attribute, 0>
|
||||
, mpl::identity<Attribute const&>
|
||||
>::type type;
|
||||
|
||||
template <typename Context>
|
||||
static type call(Attribute const& attr, Context&, mpl::false_)
|
||||
{
|
||||
return attr;
|
||||
}
|
||||
|
||||
// This handles the case where the attribute is a single element fusion
|
||||
// sequence. We silently extract the only element and treat it as the
|
||||
// attribute to generate output from.
|
||||
template <typename Context>
|
||||
static type call(Attribute const& attr, Context& ctx, mpl::true_)
|
||||
{
|
||||
return extract_from<Exposed>(fusion::at_c<0>(attr), ctx);
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
static type call(Attribute const& attr, Context& ctx)
|
||||
{
|
||||
return call(attr, ctx, is_one_element_sequence());
|
||||
}
|
||||
};
|
||||
|
||||
// This handles optional attributes.
|
||||
template <typename Attribute, typename Exposed>
|
||||
struct extract_from_attribute<boost::optional<Attribute>, Exposed>
|
||||
{
|
||||
typedef Attribute const& type;
|
||||
|
||||
template <typename Context>
|
||||
static type call(boost::optional<Attribute> const& attr, Context& ctx)
|
||||
{
|
||||
return extract_from<Exposed>(boost::get<Attribute>(attr), ctx);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Attribute, typename Exposed>
|
||||
struct extract_from_attribute<boost::optional<Attribute const>, Exposed>
|
||||
{
|
||||
typedef Attribute const& type;
|
||||
|
||||
template <typename Context>
|
||||
static type call(boost::optional<Attribute const> const& attr, Context& ctx)
|
||||
{
|
||||
return extract_from<Exposed>(boost::get<Attribute const>(attr), ctx);
|
||||
}
|
||||
};
|
||||
|
||||
// This handles attributes wrapped inside a boost::ref().
|
||||
template <typename Attribute, typename Exposed>
|
||||
struct extract_from_attribute<reference_wrapper<Attribute>, Exposed>
|
||||
{
|
||||
typedef Attribute const& type;
|
||||
|
||||
template <typename Context>
|
||||
static type call(reference_wrapper<Attribute> const& attr, Context& ctx)
|
||||
{
|
||||
return extract_from<Exposed>(attr.get(), ctx);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Attribute, typename Exposed, typename Enable>
|
||||
struct extract_from_container
|
||||
{
|
||||
typedef typename traits::container_value<Attribute const>::type
|
||||
value_type;
|
||||
typedef typename is_convertible<value_type, Exposed>::type
|
||||
is_convertible_to_value_type;
|
||||
|
||||
typedef typename mpl::if_<
|
||||
mpl::or_<
|
||||
is_same<value_type, Exposed>, is_same<Attribute, Exposed> >
|
||||
, Exposed const&, Exposed
|
||||
>::type type;
|
||||
|
||||
// handle case where container value type is convertible to result type
|
||||
// we simply return the front element of the container
|
||||
template <typename Context, typename Pred>
|
||||
static type call(Attribute const& attr, Context&, mpl::true_, Pred)
|
||||
{
|
||||
// return first element from container
|
||||
typedef typename traits::container_iterator<Attribute const>::type
|
||||
iterator_type;
|
||||
|
||||
iterator_type it = traits::begin(attr);
|
||||
type result = *it;
|
||||
++it;
|
||||
return result;
|
||||
}
|
||||
|
||||
// handle strings
|
||||
template <typename Iterator>
|
||||
static void append_to_string(Exposed& result, Iterator begin, Iterator end)
|
||||
{
|
||||
for (Iterator i = begin; i != end; ++i)
|
||||
push_back(result, *i);
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
static type call(Attribute const& attr, Context&, mpl::false_, mpl::true_)
|
||||
{
|
||||
typedef typename char_type_of<Attribute>::type char_type;
|
||||
|
||||
Exposed result;
|
||||
append_to_string(result, traits::get_begin<char_type>(attr)
|
||||
, traits::get_end<char_type>(attr));
|
||||
return result;
|
||||
}
|
||||
|
||||
// everything else gets just passed through
|
||||
template <typename Context>
|
||||
static type call(Attribute const& attr, Context&, mpl::false_, mpl::false_)
|
||||
{
|
||||
return type(attr);
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
static type call(Attribute const& attr, Context& ctx)
|
||||
{
|
||||
typedef typename mpl::and_<
|
||||
traits::is_string<Exposed>, traits::is_string<Attribute>
|
||||
>::type handle_strings;
|
||||
|
||||
// return first element from container
|
||||
return call(attr, ctx, is_convertible_to_value_type()
|
||||
, handle_strings());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Attribute>
|
||||
struct extract_from_container<Attribute, Attribute>
|
||||
{
|
||||
typedef Attribute const& type;
|
||||
|
||||
template <typename Context>
|
||||
static type call(Attribute const& attr, Context&)
|
||||
{
|
||||
return attr;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
namespace detail
|
||||
{
|
||||
// overload for non-container attributes
|
||||
template <typename Exposed, typename Attribute, typename Context>
|
||||
inline typename spirit::result_of::extract_from<Exposed, Attribute>::type
|
||||
extract_from(Attribute const& attr, Context& ctx, mpl::false_)
|
||||
{
|
||||
return extract_from_attribute<Attribute, Exposed>::call(attr, ctx);
|
||||
}
|
||||
|
||||
// overload for containers (but not for variants or optionals
|
||||
// holding containers)
|
||||
template <typename Exposed, typename Attribute, typename Context>
|
||||
inline typename spirit::result_of::extract_from<Exposed, Attribute>::type
|
||||
extract_from(Attribute const& attr, Context& ctx, mpl::true_)
|
||||
{
|
||||
return extract_from_container<Attribute, Exposed>::call(attr, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Exposed, typename Attribute, typename Context>
|
||||
inline typename spirit::result_of::extract_from<Exposed, Attribute>::type
|
||||
extract_from(Attribute const& attr, Context& ctx
|
||||
#if (defined(__GNUC__) && (__GNUC__ < 4)) || \
|
||||
(defined(__APPLE__) && defined(__INTEL_COMPILER))
|
||||
, typename enable_if<traits::not_is_unused<Attribute> >::type*
|
||||
#endif
|
||||
)
|
||||
{
|
||||
typedef typename mpl::and_<
|
||||
traits::is_container<Attribute>
|
||||
, traits::not_is_variant<Attribute>
|
||||
, traits::not_is_optional<Attribute>
|
||||
>::type is_not_wrapped_container;
|
||||
|
||||
return detail::extract_from<Exposed>(attr, ctx
|
||||
, is_not_wrapped_container());
|
||||
}
|
||||
|
||||
template <typename Exposed, typename Context>
|
||||
inline unused_type extract_from(unused_type, Context&)
|
||||
{
|
||||
return unused;
|
||||
}
|
||||
}}}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit { namespace result_of
|
||||
{
|
||||
template <typename Exposed, typename Attribute>
|
||||
struct extract_from
|
||||
: mpl::if_<
|
||||
mpl::and_<
|
||||
traits::is_container<Attribute>
|
||||
, traits::not_is_variant<Attribute>
|
||||
, traits::not_is_optional<Attribute> >
|
||||
, traits::extract_from_container<Attribute, Exposed>
|
||||
, traits::extract_from_attribute<Attribute, Exposed> >::type
|
||||
{};
|
||||
|
||||
template <typename Exposed>
|
||||
struct extract_from<Exposed, unused_type>
|
||||
{
|
||||
typedef unused_type type;
|
||||
};
|
||||
|
||||
template <typename Exposed>
|
||||
struct extract_from<Exposed, unused_type const>
|
||||
{
|
||||
typedef unused_type type;
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,60 @@
|
||||
// Copyright (c) 2001-2011 Hartmut Kaiser
|
||||
// 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(SPIRIT_KARMA_SEQUENCE_FEB_28_2007_0249PM)
|
||||
#define SPIRIT_KARMA_SEQUENCE_FEB_28_2007_0249PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace karma { namespace detail
|
||||
{
|
||||
template <typename OutputIterator, typename Context, typename Delimiter>
|
||||
struct fail_function
|
||||
{
|
||||
typedef Context context_type;
|
||||
|
||||
fail_function(OutputIterator& sink_, Context& context_
|
||||
, Delimiter const& delim_)
|
||||
: sink(sink_), ctx(context_), delim(delim_)
|
||||
{}
|
||||
|
||||
template <typename Component, typename Attribute>
|
||||
bool operator()(Component const& component, Attribute const& attr) const
|
||||
{
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
|
||||
component; // suppresses warning: C4100: 'component' : unreferenced formal parameter
|
||||
#endif
|
||||
// return true if any of the generators fail
|
||||
return !component.generate(sink, ctx, delim, attr);
|
||||
}
|
||||
|
||||
template <typename Component>
|
||||
bool operator()(Component const& component) const
|
||||
{
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
|
||||
component; // suppresses warning: C4100: 'component' : unreferenced formal parameter
|
||||
#endif
|
||||
// return true if any of the generators fail
|
||||
return !component.generate(sink, ctx, delim, unused);
|
||||
}
|
||||
|
||||
OutputIterator& sink;
|
||||
Context& ctx;
|
||||
Delimiter const& delim;
|
||||
|
||||
private:
|
||||
// silence MSVC warning C4512: assignment operator could not be generated
|
||||
fail_function& operator= (fail_function const&);
|
||||
};
|
||||
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,131 @@
|
||||
// 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_DETAIL_GENERATE_FEB_20_2007_0959AM)
|
||||
#define BOOST_SPIRIT_KARMA_DETAIL_GENERATE_FEB_20_2007_0959AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/karma/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/karma/delimit_out.hpp>
|
||||
#include <boost/spirit/home/karma/delimit_flag.hpp>
|
||||
#include <boost/spirit/home/karma/detail/output_iterator.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace karma { namespace detail
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Expr, typename Enable = void>
|
||||
struct generate_impl
|
||||
{
|
||||
// Report invalid expression error as early as possible.
|
||||
// If you got an error_invalid_expression error message here,
|
||||
// then the expression (Expr) is not a valid spirit karma expression.
|
||||
// Did you intend to use the auto_ facilities while forgetting to
|
||||
// #include <boost/spirit/include/karma_auto.hpp>?
|
||||
BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr);
|
||||
};
|
||||
|
||||
template <typename Expr>
|
||||
struct generate_impl<Expr
|
||||
, typename enable_if<traits::matches<karma::domain, Expr> >::type>
|
||||
{
|
||||
template <typename OutputIterator>
|
||||
static bool call(
|
||||
OutputIterator& target_sink
|
||||
, Expr const& expr)
|
||||
{
|
||||
typedef traits::properties_of<
|
||||
typename result_of::compile<karma::domain, Expr>::type
|
||||
> properties;
|
||||
|
||||
// wrap user supplied iterator into our own output iterator
|
||||
output_iterator<OutputIterator
|
||||
, mpl::int_<properties::value> > sink(target_sink);
|
||||
return compile<karma::domain>(expr).
|
||||
generate(sink, unused, unused, unused);
|
||||
}
|
||||
|
||||
template <typename OutputIterator, typename Properties>
|
||||
static bool call(
|
||||
detail::output_iterator<OutputIterator, Properties>& sink
|
||||
, Expr const& expr)
|
||||
{
|
||||
return compile<karma::domain>(expr).
|
||||
generate(sink, unused, unused, unused);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Expr, typename Enable = void>
|
||||
struct generate_delimited_impl
|
||||
{
|
||||
// Report invalid expression error as early as possible.
|
||||
// If you got an error_invalid_expression error message here,
|
||||
// then the expression (Expr) is not a valid spirit karma expression.
|
||||
// Did you intend to use the auto_ facilities while forgetting to
|
||||
// #include <boost/spirit/include/karma_auto.hpp>?
|
||||
BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr);
|
||||
};
|
||||
|
||||
template <typename Expr>
|
||||
struct generate_delimited_impl<Expr
|
||||
, typename enable_if<traits::matches<karma::domain, Expr> >::type>
|
||||
{
|
||||
template <typename OutputIterator, typename Delimiter>
|
||||
static bool call(
|
||||
OutputIterator& target_sink
|
||||
, Expr const& expr
|
||||
, Delimiter const& delimiter
|
||||
, BOOST_SCOPED_ENUM(delimit_flag) pre_delimit)
|
||||
{
|
||||
typedef traits::properties_of<
|
||||
typename result_of::compile<karma::domain, Expr>::type
|
||||
> properties;
|
||||
typedef traits::properties_of<
|
||||
typename result_of::compile<karma::domain, Delimiter>::type
|
||||
> delimiter_properties;
|
||||
|
||||
// wrap user supplied iterator into our own output iterator
|
||||
detail::output_iterator<OutputIterator
|
||||
, mpl::int_<properties::value | delimiter_properties::value>
|
||||
> sink(target_sink);
|
||||
return call(sink, expr, delimiter, pre_delimit);
|
||||
}
|
||||
|
||||
template <typename OutputIterator, typename Properties
|
||||
, typename Delimiter>
|
||||
static bool call(
|
||||
detail::output_iterator<OutputIterator, Properties>& sink
|
||||
, Expr const& expr
|
||||
, Delimiter const& delimiter
|
||||
, BOOST_SCOPED_ENUM(delimit_flag) pre_delimit)
|
||||
{
|
||||
// Report invalid expression error as early as possible.
|
||||
// If you got an error_invalid_expression error message here,
|
||||
// then the delimiter is not a valid spirit karma expression.
|
||||
BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Delimiter);
|
||||
|
||||
typename result_of::compile<karma::domain, Delimiter>::type const
|
||||
delimiter_ = compile<karma::domain>(delimiter);
|
||||
|
||||
if (pre_delimit == delimit_flag::predelimit &&
|
||||
!karma::delimit_out(sink, delimiter_))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return compile<karma::domain>(expr).
|
||||
generate(sink, unused, delimiter_, unused);
|
||||
}
|
||||
};
|
||||
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
// 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_DETAIL_GENERATE_AUTO_DEC_01_2009_0743PM)
|
||||
#define BOOST_SPIRIT_KARMA_DETAIL_GENERATE_AUTO_DEC_01_2009_0743PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/karma/generate.hpp>
|
||||
#include <boost/spirit/home/karma/auto/create_generator.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/mpl/not.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace karma { namespace detail
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Expr>
|
||||
struct generate_impl<Expr
|
||||
, typename enable_if<
|
||||
mpl::and_<
|
||||
traits::meta_create_exists<karma::domain, Expr>
|
||||
, mpl::not_<traits::matches<karma::domain, Expr> > >
|
||||
>::type>
|
||||
{
|
||||
template <typename OutputIterator>
|
||||
static bool call(
|
||||
OutputIterator& sink
|
||||
, Expr const& expr)
|
||||
{
|
||||
return karma::generate(sink, create_generator<Expr>(), expr);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Expr>
|
||||
struct generate_delimited_impl<Expr
|
||||
, typename enable_if<
|
||||
mpl::and_<
|
||||
traits::meta_create_exists<karma::domain, Expr>
|
||||
, mpl::not_<traits::matches<karma::domain, Expr> > >
|
||||
>::type>
|
||||
{
|
||||
template <typename OutputIterator, typename Delimiter>
|
||||
static bool call(
|
||||
OutputIterator& sink
|
||||
, Expr const& expr
|
||||
, Delimiter const& delimiter
|
||||
, BOOST_SCOPED_ENUM(delimit_flag) pre_delimit)
|
||||
{
|
||||
return karma::generate_delimited(
|
||||
sink, create_generator<Expr>(), delimiter, pre_delimit, expr);
|
||||
}
|
||||
};
|
||||
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
// 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_DETAIL_GENERATE_TO_FEB_20_2007_0417PM)
|
||||
#define BOOST_SPIRIT_KARMA_DETAIL_GENERATE_TO_FEB_20_2007_0417PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/support/char_class.hpp>
|
||||
#include <boost/spirit/home/karma/detail/output_iterator.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace karma { namespace detail
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// These utility functions insert the given parameter into the supplied
|
||||
// output iterator.
|
||||
// If the attribute is spirit's unused_type, this is a no_op.
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <
|
||||
typename OutputIterator, typename Attribute, typename CharEncoding
|
||||
, typename Tag>
|
||||
inline bool
|
||||
generate_to(OutputIterator& sink, Attribute const& p, CharEncoding, Tag)
|
||||
{
|
||||
*sink = spirit::char_class::convert<CharEncoding>::to(Tag(), p);
|
||||
++sink;
|
||||
return detail::sink_is_good(sink);
|
||||
}
|
||||
|
||||
template <typename OutputIterator, typename Attribute>
|
||||
inline bool
|
||||
generate_to(OutputIterator& sink, Attribute const& p, unused_type, unused_type)
|
||||
{
|
||||
*sink = p;
|
||||
++sink;
|
||||
return detail::sink_is_good(sink);
|
||||
}
|
||||
|
||||
template <typename OutputIterator, typename CharEncoding, typename Tag>
|
||||
inline bool generate_to(OutputIterator&, unused_type, CharEncoding, Tag)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename OutputIterator, typename Attribute>
|
||||
inline bool
|
||||
generate_to(OutputIterator& sink, Attribute const& p)
|
||||
{
|
||||
*sink = p;
|
||||
++sink;
|
||||
return detail::sink_is_good(sink);
|
||||
}
|
||||
|
||||
template <typename OutputIterator>
|
||||
inline bool generate_to(OutputIterator&, unused_type)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}}}} // namespace boost::spirit::karma::detail
|
||||
|
||||
#endif // KARMA_CORE_DETAIL_INSERT_TO_HPP
|
||||
@@ -0,0 +1,29 @@
|
||||
// Copyright (c) 2001-2011 Hartmut Kaiser
|
||||
// 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_KARMA_GET_CASETAG_JANUARY_19_2009_1107AM)
|
||||
#define BOOST_SPIRIT_KARMA_GET_CASETAG_JANUARY_19_2009_1107AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/mpl/identity.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/support/common_terminals.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace karma { namespace detail
|
||||
{
|
||||
template <typename Modifiers, bool case_modifier = false>
|
||||
struct get_casetag : mpl::identity<unused_type> {};
|
||||
|
||||
template <typename Modifiers>
|
||||
struct get_casetag<Modifiers, true>
|
||||
: mpl::if_<has_modifier<Modifiers, tag::char_code_base<tag::lower> >
|
||||
, tag::lower, tag::upper> {};
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,33 @@
|
||||
// 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_GET_STRICTTAG_APR_22_2010_1007AM)
|
||||
#define BOOST_SPIRIT_KARMA_GET_STRICTTAG_APR_22_2010_1007AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/mpl/or.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/spirit/home/support/common_terminals.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace karma { namespace detail
|
||||
{
|
||||
// the default mode for Karma is 'relaxed'
|
||||
template <
|
||||
typename Modifiers
|
||||
, typename StrictModifier = typename mpl::or_<
|
||||
has_modifier<Modifiers, tag::strict>
|
||||
, has_modifier<Modifiers, tag::relaxed> >::type>
|
||||
struct get_stricttag : mpl::false_ {};
|
||||
|
||||
// strict mode is enforced only when tag::strict is on the modifiers list
|
||||
template <typename Modifiers>
|
||||
struct get_stricttag<Modifiers, mpl::true_>
|
||||
: has_modifier<Modifiers, tag::strict> {};
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
// 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(SPIRIT_KARMA_INDIRECT_ITERATOR_JAN_19_2011_0814PM)
|
||||
#define SPIRIT_KARMA_INDIRECT_ITERATOR_JAN_19_2011_0814PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit { namespace karma { namespace detail
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// This is a wrapper for any iterator allowing to pass a reference of it
|
||||
// to the components of the sequence
|
||||
template <typename Iterator>
|
||||
class indirect_iterator
|
||||
: public boost::iterator_facade<
|
||||
indirect_iterator<Iterator>
|
||||
, typename boost::detail::iterator_traits<Iterator>::value_type
|
||||
, boost::forward_traversal_tag
|
||||
, typename boost::detail::iterator_traits<Iterator>::reference>
|
||||
{
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::value_type
|
||||
base_value_type;
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::reference
|
||||
base_reference_type;
|
||||
|
||||
typedef boost::iterator_facade<
|
||||
indirect_iterator<Iterator>, base_value_type
|
||||
, boost::forward_traversal_tag, base_reference_type
|
||||
> base_type;
|
||||
|
||||
public:
|
||||
indirect_iterator(Iterator& iter)
|
||||
: iter_(&iter)
|
||||
{}
|
||||
indirect_iterator(indirect_iterator const& iter)
|
||||
: iter_(iter.iter_)
|
||||
{}
|
||||
|
||||
private:
|
||||
friend class boost::iterator_core_access;
|
||||
|
||||
void increment()
|
||||
{
|
||||
++*iter_;
|
||||
}
|
||||
|
||||
bool equal(indirect_iterator const& other) const
|
||||
{
|
||||
return *iter_ == *other.iter_;
|
||||
}
|
||||
|
||||
base_reference_type dereference() const
|
||||
{
|
||||
return **iter_;
|
||||
}
|
||||
|
||||
private:
|
||||
Iterator* iter_;
|
||||
};
|
||||
}}}}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
template <typename Iterator>
|
||||
struct make_indirect_iterator
|
||||
{
|
||||
typedef karma::detail::indirect_iterator<Iterator> type;
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
struct make_indirect_iterator<karma::detail::indirect_iterator<Iterator> >
|
||||
{
|
||||
typedef karma::detail::indirect_iterator<Iterator> type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct make_indirect_iterator<unused_type const*>
|
||||
{
|
||||
typedef unused_type const* type;
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
struct make_indirect_iterator<Iterator const&>
|
||||
: make_indirect_iterator<Iterator const>
|
||||
{};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
+644
@@ -0,0 +1,644 @@
|
||||
// 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_OUTPUT_ITERATOR_MAY_26_2007_0506PM)
|
||||
#define BOOST_SPIRIT_KARMA_OUTPUT_ITERATOR_MAY_26_2007_0506PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
|
||||
#include <boost/spirit/home/karma/generator.hpp>
|
||||
#include <boost/spirit/home/support/iterators/ostream_iterator.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
|
||||
#if defined(BOOST_MSVC) && defined(BOOST_SPIRIT_UNICODE)
|
||||
#include <boost/spirit/home/support/char_encoding/unicode.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost { namespace spirit { namespace karma { namespace detail
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// This class is used to keep track of the current position in the output.
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
class position_sink
|
||||
{
|
||||
public:
|
||||
position_sink() : count(0), line(1), column(1) {}
|
||||
void tidy() { count = 0; line = 1; column = 1; }
|
||||
|
||||
template <typename T>
|
||||
void output(T const& value)
|
||||
{
|
||||
++count;
|
||||
if (value == '\n') {
|
||||
++line;
|
||||
column = 1;
|
||||
}
|
||||
else {
|
||||
++column;
|
||||
}
|
||||
}
|
||||
std::size_t get_count() const { return count; }
|
||||
std::size_t get_line() const { return line; }
|
||||
std::size_t get_column() const { return column; }
|
||||
|
||||
private:
|
||||
std::size_t count;
|
||||
std::size_t line;
|
||||
std::size_t column;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct position_policy
|
||||
{
|
||||
position_policy() {}
|
||||
position_policy(position_policy const& rhs)
|
||||
: track_position_data(rhs.track_position_data) {}
|
||||
|
||||
template <typename T>
|
||||
void output(T const& value)
|
||||
{
|
||||
// track position in the output
|
||||
track_position_data.output(value);
|
||||
}
|
||||
|
||||
// return the current count in the output
|
||||
std::size_t get_out_count() const
|
||||
{
|
||||
return track_position_data.get_count();
|
||||
}
|
||||
|
||||
// return the current line in the output
|
||||
std::size_t get_line() const
|
||||
{
|
||||
return track_position_data.get_line();
|
||||
}
|
||||
|
||||
// return the current column in the output
|
||||
std::size_t get_column() const
|
||||
{
|
||||
return track_position_data.get_column();
|
||||
}
|
||||
|
||||
private:
|
||||
position_sink track_position_data; // for position tracking
|
||||
};
|
||||
|
||||
struct no_position_policy
|
||||
{
|
||||
no_position_policy() {}
|
||||
no_position_policy(no_position_policy const&) {}
|
||||
|
||||
template <typename T>
|
||||
void output(T const& /*value*/) {}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// This class is used to count the number of characters streamed into the
|
||||
// output.
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename OutputIterator>
|
||||
class counting_sink : boost::noncopyable
|
||||
{
|
||||
public:
|
||||
counting_sink(OutputIterator& sink_, std::size_t count_ = 0
|
||||
, bool enabled = true)
|
||||
: count(count_), initial_count(count), prev_count(0), sink(sink_)
|
||||
{
|
||||
prev_count = sink.chain_counting(enabled ? this : NULL);
|
||||
}
|
||||
~counting_sink()
|
||||
{
|
||||
if (prev_count) // propagate count
|
||||
prev_count->update_count(count-initial_count);
|
||||
sink.chain_counting(prev_count);
|
||||
}
|
||||
|
||||
void output()
|
||||
{
|
||||
++count;
|
||||
}
|
||||
std::size_t get_count() const { return count; }
|
||||
|
||||
// propagate count from embedded counters
|
||||
void update_count(std::size_t c)
|
||||
{
|
||||
count += c;
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t count;
|
||||
std::size_t initial_count;
|
||||
counting_sink* prev_count; // previous counter in chain
|
||||
OutputIterator& sink;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename OutputIterator>
|
||||
struct counting_policy
|
||||
{
|
||||
public:
|
||||
counting_policy() : count(NULL) {}
|
||||
counting_policy(counting_policy const& rhs) : count(rhs.count) {}
|
||||
|
||||
// functions related to counting
|
||||
counting_sink<OutputIterator>* chain_counting(
|
||||
counting_sink<OutputIterator>* count_data)
|
||||
{
|
||||
counting_sink<OutputIterator>* prev_count = count;
|
||||
count = count_data;
|
||||
return prev_count;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void output(T const&)
|
||||
{
|
||||
// count characters, if appropriate
|
||||
if (NULL != count)
|
||||
count->output();
|
||||
}
|
||||
|
||||
private:
|
||||
counting_sink<OutputIterator>* count; // for counting
|
||||
};
|
||||
|
||||
struct no_counting_policy
|
||||
{
|
||||
no_counting_policy() {}
|
||||
no_counting_policy(no_counting_policy const&) {}
|
||||
|
||||
template <typename T>
|
||||
void output(T const& /*value*/) {}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// The following classes are used to intercept the output into a buffer
|
||||
// allowing to do things like alignment, character escaping etc.
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
class buffer_sink : boost::noncopyable
|
||||
{
|
||||
// wchar_t is only 16-bits on Windows. If BOOST_SPIRIT_UNICODE is
|
||||
// defined, the character type is 32-bits wide so we need to make
|
||||
// sure the buffer is at least that wide.
|
||||
#if defined(BOOST_MSVC) && defined(BOOST_SPIRIT_UNICODE)
|
||||
typedef spirit::char_encoding::unicode::char_type buffer_char_type;
|
||||
#else
|
||||
typedef wchar_t buffer_char_type;
|
||||
#endif
|
||||
|
||||
public:
|
||||
buffer_sink()
|
||||
: width(0) {}
|
||||
|
||||
~buffer_sink()
|
||||
{
|
||||
tidy();
|
||||
}
|
||||
|
||||
void enable(std::size_t width_)
|
||||
{
|
||||
tidy(); // release existing buffer
|
||||
width = (width_ == std::size_t(-1)) ? 0 : width_;
|
||||
buffer.reserve(width);
|
||||
}
|
||||
|
||||
void tidy()
|
||||
{
|
||||
buffer.clear();
|
||||
width = 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void output(T const& value)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(sizeof(T) <= sizeof(buffer_char_type));
|
||||
buffer.push_back(value);
|
||||
}
|
||||
|
||||
template <typename OutputIterator_>
|
||||
bool copy(OutputIterator_& sink, std::size_t maxwidth) const
|
||||
{
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4267)
|
||||
#endif
|
||||
typename std::basic_string<buffer_char_type>::const_iterator end =
|
||||
buffer.begin() + (std::min)(buffer.size(), maxwidth);
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
std::copy(buffer.begin(), end, sink);
|
||||
return true;
|
||||
}
|
||||
template <typename RestIterator>
|
||||
bool copy_rest(RestIterator& sink, std::size_t start_at) const
|
||||
{
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4267)
|
||||
#endif
|
||||
typename std::basic_string<buffer_char_type>::const_iterator begin =
|
||||
buffer.begin() + (std::min)(buffer.size(), start_at);
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
std::copy(begin, buffer.end(), sink);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::size_t buffer_size() const
|
||||
{
|
||||
return buffer.size();
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t width;
|
||||
std::basic_string<buffer_char_type> buffer;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct buffering_policy
|
||||
{
|
||||
public:
|
||||
buffering_policy() : buffer(NULL) {}
|
||||
buffering_policy(buffering_policy const& rhs) : buffer(rhs.buffer) {}
|
||||
|
||||
// functions related to buffering
|
||||
buffer_sink* chain_buffering(buffer_sink* buffer_data)
|
||||
{
|
||||
buffer_sink* prev_buffer = buffer;
|
||||
buffer = buffer_data;
|
||||
return prev_buffer;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool output(T const& value)
|
||||
{
|
||||
// buffer characters, if appropriate
|
||||
if (NULL != buffer) {
|
||||
buffer->output(value);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool has_buffer() const { return NULL != buffer; }
|
||||
|
||||
private:
|
||||
buffer_sink* buffer;
|
||||
};
|
||||
|
||||
struct no_buffering_policy
|
||||
{
|
||||
no_buffering_policy() {}
|
||||
no_buffering_policy(no_counting_policy const&) {}
|
||||
|
||||
template <typename T>
|
||||
bool output(T const& /*value*/)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool has_buffer() const { return false; }
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// forward declaration only
|
||||
template <typename OutputIterator>
|
||||
struct enable_buffering;
|
||||
|
||||
template <typename OutputIterator, typename Properties
|
||||
, typename Derived = unused_type>
|
||||
class output_iterator;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Buffering, typename Counting, typename Tracking>
|
||||
struct output_iterator_base : Buffering, Counting, Tracking
|
||||
{
|
||||
typedef Buffering buffering_policy;
|
||||
typedef Counting counting_policy;
|
||||
typedef Tracking tracking_policy;
|
||||
|
||||
output_iterator_base() {}
|
||||
output_iterator_base(output_iterator_base const& rhs)
|
||||
: buffering_policy(rhs), counting_policy(rhs), tracking_policy(rhs)
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
bool output(T const& value)
|
||||
{
|
||||
this->counting_policy::output(value);
|
||||
this->tracking_policy::output(value);
|
||||
return this->buffering_policy::output(value);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Buffering, typename Counting, typename Tracking>
|
||||
struct disabling_output_iterator : Buffering, Counting, Tracking
|
||||
{
|
||||
typedef Buffering buffering_policy;
|
||||
typedef Counting counting_policy;
|
||||
typedef Tracking tracking_policy;
|
||||
|
||||
disabling_output_iterator() : do_output(true) {}
|
||||
disabling_output_iterator(disabling_output_iterator const& rhs)
|
||||
: buffering_policy(rhs), counting_policy(rhs), tracking_policy(rhs)
|
||||
, do_output(rhs.do_output)
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
bool output(T const& value)
|
||||
{
|
||||
if (!do_output)
|
||||
return false;
|
||||
|
||||
this->counting_policy::output(value);
|
||||
this->tracking_policy::output(value);
|
||||
return this->buffering_policy::output(value);
|
||||
}
|
||||
|
||||
bool do_output;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename OutputIterator, typename Properties, typename Derived>
|
||||
struct make_output_iterator
|
||||
{
|
||||
// get the most derived type of this class
|
||||
typedef typename mpl::if_<
|
||||
traits::not_is_unused<Derived>, Derived
|
||||
, output_iterator<OutputIterator, Properties, Derived>
|
||||
>::type most_derived_type;
|
||||
|
||||
enum { properties = Properties::value };
|
||||
|
||||
typedef typename mpl::if_c<
|
||||
(properties & generator_properties::tracking) ? true : false
|
||||
, position_policy, no_position_policy
|
||||
>::type tracking_type;
|
||||
|
||||
typedef typename mpl::if_c<
|
||||
(properties & generator_properties::buffering) ? true : false
|
||||
, buffering_policy, no_buffering_policy
|
||||
>::type buffering_type;
|
||||
|
||||
typedef typename mpl::if_c<
|
||||
(properties & generator_properties::counting) ? true : false
|
||||
, counting_policy<most_derived_type>, no_counting_policy
|
||||
>::type counting_type;
|
||||
|
||||
typedef typename mpl::if_c<
|
||||
(properties & generator_properties::disabling) ? true : false
|
||||
, disabling_output_iterator<buffering_type, counting_type, tracking_type>
|
||||
, output_iterator_base<buffering_type, counting_type, tracking_type>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Karma uses an output iterator wrapper for all output operations. This
|
||||
// is necessary to avoid the dreaded 'scanner business' problem, i.e. the
|
||||
// dependency of rules and grammars on the used output iterator.
|
||||
//
|
||||
// By default the user supplied output iterator is wrapped inside an
|
||||
// instance of this internal output_iterator class.
|
||||
//
|
||||
// This output_iterator class normally just forwards to the embedded user
|
||||
// supplied iterator. But it is possible to enable additional functionality
|
||||
// on demand, such as counting, buffering, and position tracking.
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename OutputIterator, typename Properties, typename Derived>
|
||||
class output_iterator
|
||||
: public make_output_iterator<OutputIterator, Properties, Derived>::type
|
||||
{
|
||||
private:
|
||||
// base iterator type
|
||||
typedef typename make_output_iterator<
|
||||
OutputIterator, Properties, Derived>::type base_iterator;
|
||||
|
||||
public:
|
||||
typedef std::output_iterator_tag iterator_category;
|
||||
typedef void value_type;
|
||||
typedef void difference_type;
|
||||
typedef void pointer;
|
||||
typedef void reference;
|
||||
|
||||
explicit output_iterator(OutputIterator& sink_)
|
||||
: sink(&sink_)
|
||||
{}
|
||||
output_iterator(output_iterator const& rhs)
|
||||
: base_iterator(rhs), sink(rhs.sink)
|
||||
{}
|
||||
|
||||
output_iterator& operator*() { return *this; }
|
||||
output_iterator& operator++()
|
||||
{
|
||||
if (!this->base_iterator::has_buffer())
|
||||
++(*sink); // increment only if not buffering
|
||||
return *this;
|
||||
}
|
||||
output_iterator operator++(int)
|
||||
{
|
||||
if (!this->base_iterator::has_buffer()) {
|
||||
output_iterator t(*this);
|
||||
++(*sink);
|
||||
return t;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
// 'argument' : conversion from '...' to '...', possible loss of data
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable: 4244)
|
||||
#endif
|
||||
template <typename T>
|
||||
void operator=(T const& value)
|
||||
{
|
||||
if (this->base_iterator::output(value))
|
||||
*(*sink) = value;
|
||||
}
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
|
||||
// plain output iterators are considered to be good all the time
|
||||
bool good() const { return true; }
|
||||
|
||||
// allow to access underlying output iterator
|
||||
OutputIterator& base() { return *sink; }
|
||||
|
||||
protected:
|
||||
// this is the wrapped user supplied output iterator
|
||||
OutputIterator* sink;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename Elem, typename Traits, typename Properties>
|
||||
class output_iterator<karma::ostream_iterator<T, Elem, Traits>, Properties>
|
||||
: public output_iterator<karma::ostream_iterator<T, Elem, Traits>, Properties
|
||||
, output_iterator<karma::ostream_iterator<T, Elem, Traits>, Properties> >
|
||||
{
|
||||
private:
|
||||
typedef output_iterator<karma::ostream_iterator<T, Elem, Traits>, Properties
|
||||
, output_iterator<karma::ostream_iterator<T, Elem, Traits>, Properties>
|
||||
> base_type;
|
||||
typedef karma::ostream_iterator<T, Elem, Traits> base_iterator_type;
|
||||
typedef std::basic_ostream<Elem, Traits> ostream_type;
|
||||
|
||||
public:
|
||||
output_iterator(base_iterator_type& sink)
|
||||
: base_type(sink) {}
|
||||
|
||||
ostream_type& get_ostream() { return (*this->sink).get_ostream(); }
|
||||
ostream_type const& get_ostream() const { return (*this->sink).get_ostream(); }
|
||||
|
||||
// expose good bit of underlying stream object
|
||||
bool good() const { return (*this->sink).get_ostream().good(); }
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Helper class for exception safe enabling of character counting in the
|
||||
// output iterator
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename OutputIterator>
|
||||
struct enable_counting
|
||||
{
|
||||
enable_counting(OutputIterator& sink_, std::size_t count = 0)
|
||||
: count_data(sink_, count) {}
|
||||
|
||||
// get number of characters counted since last enable
|
||||
std::size_t count() const
|
||||
{
|
||||
return count_data.get_count();
|
||||
}
|
||||
|
||||
private:
|
||||
counting_sink<OutputIterator> count_data; // for counting
|
||||
};
|
||||
|
||||
template <typename OutputIterator>
|
||||
struct disable_counting
|
||||
{
|
||||
disable_counting(OutputIterator& sink_)
|
||||
: count_data(sink_, 0, false) {}
|
||||
|
||||
private:
|
||||
counting_sink<OutputIterator> count_data;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Helper class for exception safe enabling of character buffering in the
|
||||
// output iterator
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename OutputIterator>
|
||||
struct enable_buffering
|
||||
{
|
||||
enable_buffering(OutputIterator& sink_
|
||||
, std::size_t width = std::size_t(-1))
|
||||
: sink(sink_), prev_buffer(NULL), enabled(false)
|
||||
{
|
||||
buffer_data.enable(width);
|
||||
prev_buffer = sink.chain_buffering(&buffer_data);
|
||||
enabled = true;
|
||||
}
|
||||
~enable_buffering()
|
||||
{
|
||||
disable();
|
||||
}
|
||||
|
||||
// reset buffer chain to initial state
|
||||
void disable()
|
||||
{
|
||||
if (enabled) {
|
||||
BOOST_VERIFY(&buffer_data == sink.chain_buffering(prev_buffer));
|
||||
enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
// copy to the underlying sink whatever is in the local buffer
|
||||
bool buffer_copy(std::size_t maxwidth = std::size_t(-1)
|
||||
, bool disable_ = true)
|
||||
{
|
||||
if (disable_)
|
||||
disable();
|
||||
return buffer_data.copy(sink, maxwidth) && sink.good();
|
||||
}
|
||||
|
||||
// return number of characters stored in the buffer
|
||||
std::size_t buffer_size() const
|
||||
{
|
||||
return buffer_data.buffer_size();
|
||||
}
|
||||
|
||||
// copy to the remaining characters to the specified sink
|
||||
template <typename RestIterator>
|
||||
bool buffer_copy_rest(RestIterator& sink, std::size_t start_at = 0) const
|
||||
{
|
||||
return buffer_data.copy_rest(sink, start_at);
|
||||
}
|
||||
|
||||
// copy the contents to the given output iterator
|
||||
template <typename OutputIterator_>
|
||||
bool buffer_copy_to(OutputIterator_& sink
|
||||
, std::size_t maxwidth = std::size_t(-1)) const
|
||||
{
|
||||
return buffer_data.copy(sink, maxwidth);
|
||||
}
|
||||
|
||||
private:
|
||||
OutputIterator& sink;
|
||||
buffer_sink buffer_data; // for buffering
|
||||
buffer_sink* prev_buffer; // previous buffer in chain
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Helper class for exception safe disabling of output
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename OutputIterator>
|
||||
struct disable_output
|
||||
{
|
||||
disable_output(OutputIterator& sink_)
|
||||
: sink(sink_), prev_do_output(sink.do_output)
|
||||
{
|
||||
sink.do_output = false;
|
||||
}
|
||||
~disable_output()
|
||||
{
|
||||
sink.do_output = prev_do_output;
|
||||
}
|
||||
|
||||
OutputIterator& sink;
|
||||
bool prev_do_output;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Sink>
|
||||
bool sink_is_good(Sink const&)
|
||||
{
|
||||
return true; // the general case is always good
|
||||
}
|
||||
|
||||
template <typename OutputIterator, typename Derived>
|
||||
bool sink_is_good(output_iterator<OutputIterator, Derived> const& sink)
|
||||
{
|
||||
return sink.good(); // our own output iterators are handled separately
|
||||
}
|
||||
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
|
||||
+392
@@ -0,0 +1,392 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Hartmut Kaiser
|
||||
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(SPIRIT_PASS_CONTAINER_MAR_15_2009_0114PM)
|
||||
#define SPIRIT_PASS_CONTAINER_MAR_15_2009_0114PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/karma/detail/attributes.hpp>
|
||||
#include <boost/spirit/home/support/container.hpp>
|
||||
#include <boost/spirit/home/support/handles_container.hpp>
|
||||
#include <boost/spirit/home/support/detail/hold_any.hpp>
|
||||
#include <boost/type_traits/is_base_of.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/mpl/or.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat.hpp>
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
#include <boost/fusion/include/deduce_sequence.hpp>
|
||||
|
||||
#include <boost/mpl/print.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace karma { namespace detail
|
||||
{
|
||||
// Helper meta-function allowing to evaluate weak substitutability and
|
||||
// negate the result if the predicate (Sequence) is not true
|
||||
template <typename Sequence, typename Attribute, typename ValueType>
|
||||
struct negate_weak_substitute_if_not
|
||||
: mpl::if_<
|
||||
Sequence
|
||||
, typename traits::is_weak_substitute<Attribute, ValueType>::type
|
||||
, typename mpl::not_<
|
||||
traits::is_weak_substitute<Attribute, ValueType>
|
||||
>::type>
|
||||
{};
|
||||
|
||||
// pass_through_container: utility to check decide whether a provided
|
||||
// container attribute needs to be passed through to the current component
|
||||
// or of we need to split the container by passing along instances of its
|
||||
// value type
|
||||
|
||||
// if the expected attribute of the current component is neither a Fusion
|
||||
// sequence nor a container, we will pass through the provided container
|
||||
// only if its value type is not compatible with the component
|
||||
template <typename Container, typename ValueType, typename Attribute
|
||||
, typename Sequence, typename Enable = void>
|
||||
struct pass_through_container_base
|
||||
: negate_weak_substitute_if_not<Sequence, ValueType, Attribute>
|
||||
{};
|
||||
|
||||
// Specialization for fusion sequences, in this case we check whether all
|
||||
// the types in the sequence are convertible to the lhs attribute.
|
||||
//
|
||||
// We return false if the rhs attribute itself is a fusion sequence, which
|
||||
// is compatible with the LHS sequence (we want to pass through this
|
||||
// attribute without it being split apart).
|
||||
template <typename Container, typename ValueType, typename Attribute
|
||||
, typename Sequence = mpl::true_>
|
||||
struct not_compatible_element
|
||||
: mpl::and_<
|
||||
negate_weak_substitute_if_not<Sequence, Container, Attribute>
|
||||
, negate_weak_substitute_if_not<Sequence, ValueType, Attribute> >
|
||||
{};
|
||||
|
||||
// If the value type of the container is not a Fusion sequence, we pass
|
||||
// through the container if each of the elements of the Attribute
|
||||
// sequence is compatible with either the container or its value type.
|
||||
template <typename Container, typename ValueType, typename Attribute
|
||||
, typename Sequence
|
||||
, bool IsSequence = fusion::traits::is_sequence<ValueType>::value>
|
||||
struct pass_through_container_fusion_sequence
|
||||
{
|
||||
typedef typename mpl::find_if<
|
||||
Attribute, not_compatible_element<Container, ValueType, mpl::_1>
|
||||
>::type iter;
|
||||
typedef typename mpl::end<Attribute>::type end;
|
||||
|
||||
typedef typename is_same<iter, end>::type type;
|
||||
};
|
||||
|
||||
// If both, the Attribute and the value type of the provided container
|
||||
// are Fusion sequences, we pass the container only if the two
|
||||
// sequences are not compatible.
|
||||
template <typename Container, typename ValueType, typename Attribute
|
||||
, typename Sequence>
|
||||
struct pass_through_container_fusion_sequence<
|
||||
Container, ValueType, Attribute, Sequence, true>
|
||||
{
|
||||
typedef typename mpl::find_if<
|
||||
Attribute
|
||||
, not_compatible_element<Container, ValueType, mpl::_1, Sequence>
|
||||
>::type iter;
|
||||
typedef typename mpl::end<Attribute>::type end;
|
||||
|
||||
typedef typename is_same<iter, end>::type type;
|
||||
};
|
||||
|
||||
template <typename Container, typename ValueType, typename Attribute
|
||||
, typename Sequence>
|
||||
struct pass_through_container_base<Container, ValueType, Attribute
|
||||
, Sequence
|
||||
, typename enable_if<fusion::traits::is_sequence<Attribute> >::type>
|
||||
: pass_through_container_fusion_sequence<
|
||||
Container, ValueType, Attribute, Sequence>
|
||||
{};
|
||||
|
||||
// Specialization for containers
|
||||
//
|
||||
// If the value type of the attribute of the current component is not
|
||||
// a Fusion sequence, we have to pass through the provided container if
|
||||
// both are compatible.
|
||||
template <typename Container, typename ValueType, typename Attribute
|
||||
, typename Sequence, typename AttributeValueType
|
||||
, bool IsSequence = fusion::traits::is_sequence<AttributeValueType>::value>
|
||||
struct pass_through_container_container
|
||||
: mpl::or_<
|
||||
traits::is_weak_substitute<Container, Attribute>
|
||||
, traits::is_weak_substitute<Container, AttributeValueType> >
|
||||
{};
|
||||
|
||||
// If the value type of the exposed container attribute is a Fusion
|
||||
// sequence, we use the already existing logic for those.
|
||||
template <typename Container, typename ValueType, typename Attribute
|
||||
, typename Sequence, typename AttributeValueType>
|
||||
struct pass_through_container_container<
|
||||
Container, ValueType, Attribute, Sequence, AttributeValueType, true>
|
||||
: pass_through_container_fusion_sequence<
|
||||
Container, ValueType, AttributeValueType, Sequence>
|
||||
{};
|
||||
|
||||
template <typename Container, typename ValueType, typename Attribute
|
||||
, typename Sequence>
|
||||
struct pass_through_container_base<Container, ValueType, Attribute
|
||||
, Sequence
|
||||
, typename enable_if<traits::is_container<Attribute> >::type>
|
||||
: detail::pass_through_container_container<
|
||||
Container, ValueType, Attribute, Sequence
|
||||
, typename traits::container_value<Attribute>::type>
|
||||
{};
|
||||
|
||||
// Specialization for exposed optional attributes
|
||||
//
|
||||
// If the type embedded in the exposed optional is not a Fusion
|
||||
// sequence we pass through the container attribute if it is compatible
|
||||
// either to the optionals embedded type or to the containers value
|
||||
// type.
|
||||
template <typename Container, typename ValueType, typename Attribute
|
||||
, typename Sequence
|
||||
, bool IsSequence = fusion::traits::is_sequence<Attribute>::value>
|
||||
struct pass_through_container_optional
|
||||
: mpl::or_<
|
||||
traits::is_weak_substitute<Container, Attribute>
|
||||
, traits::is_weak_substitute<ValueType, Attribute> >
|
||||
{};
|
||||
|
||||
// If the embedded type of the exposed optional attribute is a Fusion
|
||||
// sequence, we use the already existing logic for those.
|
||||
template <typename Container, typename ValueType, typename Attribute
|
||||
, typename Sequence>
|
||||
struct pass_through_container_optional<
|
||||
Container, ValueType, Attribute, Sequence, true>
|
||||
: pass_through_container_fusion_sequence<
|
||||
Container, ValueType, Attribute, Sequence>
|
||||
{};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Container, typename ValueType, typename Attribute
|
||||
, typename Sequence>
|
||||
struct pass_through_container
|
||||
: pass_through_container_base<Container, ValueType, Attribute, Sequence>
|
||||
{};
|
||||
|
||||
// Handle optional attributes
|
||||
template <typename Container, typename ValueType, typename Attribute
|
||||
, typename Sequence>
|
||||
struct pass_through_container<
|
||||
Container, ValueType, boost::optional<Attribute>, Sequence>
|
||||
: pass_through_container_optional<
|
||||
Container, ValueType, Attribute, Sequence>
|
||||
{};
|
||||
|
||||
// If both, the containers value type and the exposed attribute type are
|
||||
// optionals we are allowed to pass through the container only if the
|
||||
// embedded types of those optionals are not compatible.
|
||||
template <typename Container, typename ValueType, typename Attribute
|
||||
, typename Sequence>
|
||||
struct pass_through_container<
|
||||
Container, boost::optional<ValueType>, boost::optional<Attribute>
|
||||
, Sequence>
|
||||
: mpl::not_<traits::is_weak_substitute<ValueType, Attribute> >
|
||||
{};
|
||||
|
||||
// Specialization for exposed variant attributes
|
||||
//
|
||||
// We pass through the container attribute if at least one of the embedded
|
||||
// types in the variant requires to pass through the attribute
|
||||
|
||||
#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
|
||||
template <typename Container, typename ValueType, typename Sequence
|
||||
, typename T>
|
||||
struct pass_through_container<Container, ValueType, boost::variant<T>
|
||||
, Sequence>
|
||||
: pass_through_container<Container, ValueType, T, Sequence>
|
||||
{};
|
||||
|
||||
template <typename Container, typename ValueType, typename Sequence
|
||||
, typename T0, typename ...TN>
|
||||
struct pass_through_container<Container, ValueType
|
||||
, boost::variant<T0, TN...>, Sequence>
|
||||
: mpl::bool_<pass_through_container<
|
||||
Container, ValueType, T0, Sequence
|
||||
>::type::value || pass_through_container<
|
||||
Container, ValueType, boost::variant<TN...>, Sequence
|
||||
>::type::value>
|
||||
{};
|
||||
#else
|
||||
#define BOOST_SPIRIT_PASS_THROUGH_CONTAINER(z, N, _) \
|
||||
pass_through_container<Container, ValueType, \
|
||||
BOOST_PP_CAT(T, N), Sequence>::type::value || \
|
||||
/***/
|
||||
|
||||
// make sure unused variant parameters do not affect the outcome
|
||||
template <typename Container, typename ValueType, typename Sequence>
|
||||
struct pass_through_container<Container, ValueType
|
||||
, boost::detail::variant::void_, Sequence>
|
||||
: mpl::false_
|
||||
{};
|
||||
|
||||
template <typename Container, typename ValueType, typename Sequence
|
||||
, BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct pass_through_container<Container, ValueType
|
||||
, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Sequence>
|
||||
: mpl::bool_<BOOST_PP_REPEAT(BOOST_VARIANT_LIMIT_TYPES
|
||||
, BOOST_SPIRIT_PASS_THROUGH_CONTAINER, _) false>
|
||||
{};
|
||||
|
||||
#undef BOOST_SPIRIT_PASS_THROUGH_CONTAINER
|
||||
#endif
|
||||
}}}}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// forwarding customization point for domain karma::domain
|
||||
template <typename Container, typename ValueType, typename Attribute
|
||||
, typename Sequence>
|
||||
struct pass_through_container<
|
||||
Container, ValueType, Attribute, Sequence, karma::domain>
|
||||
: karma::detail::pass_through_container<
|
||||
Container, ValueType, Attribute, Sequence>
|
||||
{};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace karma { namespace detail
|
||||
{
|
||||
template <typename Iterator>
|
||||
struct pass_container_base
|
||||
{
|
||||
pass_container_base(Iterator begin, Iterator end)
|
||||
: iter(begin), end(end)
|
||||
{}
|
||||
|
||||
mutable Iterator iter;
|
||||
mutable Iterator end;
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
struct pass_container_base<Iterator&>
|
||||
{
|
||||
pass_container_base(Iterator& begin, Iterator& end)
|
||||
: iter(begin), end(end)
|
||||
{}
|
||||
|
||||
Iterator& iter;
|
||||
Iterator& end;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// This function handles the case where the attribute (Attr) given
|
||||
// to the sequence is an STL container. This is a wrapper around F.
|
||||
// The function F does the actual generating.
|
||||
template <typename F, typename Attr, typename Iterator, typename Sequence>
|
||||
struct pass_container : pass_container_base<Iterator>
|
||||
{
|
||||
typedef pass_container_base<Iterator> base_type;
|
||||
typedef typename F::context_type context_type;
|
||||
|
||||
pass_container(F const& f, Iterator begin, Iterator end)
|
||||
: base_type(begin, end)
|
||||
, f(f)
|
||||
{}
|
||||
|
||||
bool is_at_end() const
|
||||
{
|
||||
return traits::compare(this->iter, this->end);
|
||||
}
|
||||
|
||||
void next()
|
||||
{
|
||||
traits::next(this->iter);
|
||||
}
|
||||
|
||||
// this is for the case when the current element expects an attribute
|
||||
// which is taken from the next entry in the container
|
||||
template <typename Component>
|
||||
bool dispatch_container(Component const& component, mpl::false_) const
|
||||
{
|
||||
// get the next value to generate from container
|
||||
if (!is_at_end() && !f(component, traits::deref(this->iter)))
|
||||
{
|
||||
// needs to return false as long as everything is ok
|
||||
traits::next(this->iter);
|
||||
return false;
|
||||
}
|
||||
|
||||
// either no elements available any more or generation failed
|
||||
return true;
|
||||
}
|
||||
|
||||
// this is for the case when the current element is able to handle an
|
||||
// attribute which is a container itself, this element will push its
|
||||
// data directly into the attribute container
|
||||
template <typename Component>
|
||||
bool dispatch_container(Component const& component, mpl::true_) const
|
||||
{
|
||||
return f(component, make_iterator_range(this->iter, this->end));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// this is for the case when the current element doesn't expect an
|
||||
// attribute
|
||||
template <typename Component>
|
||||
bool dispatch_attribute(Component const& component, mpl::false_) const
|
||||
{
|
||||
return f(component, unused);
|
||||
}
|
||||
|
||||
// the current element expects an attribute
|
||||
template <typename Component>
|
||||
bool dispatch_attribute(Component const& component, mpl::true_) const
|
||||
{
|
||||
typedef typename traits::container_value<Attr>::type value_type;
|
||||
typedef typename
|
||||
traits::attribute_of<Component, context_type>::type
|
||||
lhs_attribute;
|
||||
|
||||
// this predicate detects, whether the value type of the container
|
||||
// attribute is a substitute for the attribute of the current
|
||||
// element
|
||||
typedef mpl::and_<
|
||||
traits::handles_container<Component, Attr, context_type>
|
||||
, traits::pass_through_container<
|
||||
Attr, value_type, lhs_attribute, Sequence, karma::domain>
|
||||
> predicate;
|
||||
|
||||
return dispatch_container(component, predicate());
|
||||
}
|
||||
|
||||
// Dispatches to dispatch_main depending on the attribute type
|
||||
// of the Component
|
||||
template <typename Component>
|
||||
bool operator()(Component const& component) const
|
||||
{
|
||||
// we need to dispatch depending on the type of the attribute
|
||||
// of the current element (component). If this is has no attribute
|
||||
// we shouldn't use an element of the container but unused_type
|
||||
// instead
|
||||
typedef traits::not_is_unused<
|
||||
typename traits::attribute_of<Component, context_type>::type
|
||||
> predicate;
|
||||
|
||||
return dispatch_attribute(component, predicate());
|
||||
}
|
||||
|
||||
F f;
|
||||
|
||||
private:
|
||||
// silence MSVC warning C4512: assignment operator could not be generated
|
||||
pass_container& operator= (pass_container const&);
|
||||
};
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,76 @@
|
||||
// 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_STRING_COMPARE_AUG_08_2009_0756PM)
|
||||
#define BOOST_SPIRIT_KARMA_STRING_COMPARE_AUG_08_2009_0756PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <boost/spirit/home/support/char_class.hpp>
|
||||
#include <boost/spirit/home/karma/detail/generate_to.hpp>
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace karma { namespace detail
|
||||
{
|
||||
template <typename Char>
|
||||
bool string_compare(Char const* attr, Char const* lit)
|
||||
{
|
||||
Char ch_attr = *attr;
|
||||
Char ch_lit = *lit;
|
||||
|
||||
while (!!ch_lit && !!ch_attr)
|
||||
{
|
||||
if (ch_attr != ch_lit)
|
||||
return false;
|
||||
|
||||
ch_attr = *++attr;
|
||||
ch_lit = *++lit;
|
||||
}
|
||||
|
||||
return !ch_lit && !ch_attr;
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
bool string_compare(Char const* attr, Char const* lit, unused_type, unused_type)
|
||||
{
|
||||
return string_compare(attr, lit);
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
bool string_compare(unused_type, Char const*, unused_type, unused_type)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Char, typename CharEncoding, typename Tag>
|
||||
bool string_compare(Char const* attr, Char const* lit, CharEncoding, Tag)
|
||||
{
|
||||
Char ch_attr = *attr;
|
||||
Char ch_lit = spirit::char_class::convert<CharEncoding>::to(Tag(), *lit);
|
||||
|
||||
while (!!ch_lit && !!ch_attr)
|
||||
{
|
||||
if (ch_attr != ch_lit)
|
||||
return false;
|
||||
|
||||
ch_attr = *++attr;
|
||||
ch_lit = spirit::char_class::convert<CharEncoding>::to(Tag(), *++lit);
|
||||
}
|
||||
|
||||
return !ch_lit && !ch_attr;
|
||||
}
|
||||
|
||||
template <typename Char, typename CharEncoding, typename Tag>
|
||||
bool string_compare(unused_type, Char const*, CharEncoding, Tag)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
// 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_STRING_GENERATE_FEB_23_2007_1232PM)
|
||||
#define BOOST_SPIRIT_KARMA_STRING_GENERATE_FEB_23_2007_1232PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <boost/spirit/home/support/char_class.hpp>
|
||||
#include <boost/spirit/home/karma/detail/generate_to.hpp>
|
||||
#include <boost/range/const_iterator.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace karma { namespace detail
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// pass through character transformation
|
||||
struct pass_through_filter
|
||||
{
|
||||
template <typename Char>
|
||||
Char operator()(Char ch) const
|
||||
{
|
||||
return ch;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename CharEncoding, typename Tag>
|
||||
struct encoding_filter
|
||||
{
|
||||
template <typename Char>
|
||||
Char operator()(Char ch) const
|
||||
{
|
||||
return spirit::char_class::convert<CharEncoding>::to(Tag(), ch);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// generate a string given by a std::string, applying the given filter
|
||||
template <typename OutputIterator, typename Char, typename Filter>
|
||||
inline bool string_generate(OutputIterator& sink, Char const* str
|
||||
, Filter filter)
|
||||
{
|
||||
for (Char ch = *str; ch != 0; ch = *++str)
|
||||
{
|
||||
*sink = filter(ch);
|
||||
++sink;
|
||||
}
|
||||
return detail::sink_is_good(sink);
|
||||
}
|
||||
|
||||
template <typename OutputIterator, typename Container, typename Filter>
|
||||
inline bool string_generate(OutputIterator& sink
|
||||
, Container const& c, Filter filter)
|
||||
{
|
||||
typedef typename traits::container_iterator<Container const>::type
|
||||
iterator;
|
||||
|
||||
const iterator end = boost::end(c);
|
||||
for (iterator it = boost::begin(c); it != end; ++it)
|
||||
{
|
||||
*sink = filter(*it);
|
||||
++sink;
|
||||
}
|
||||
return detail::sink_is_good(sink);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// generate a string without any transformation
|
||||
template <typename OutputIterator, typename Char>
|
||||
inline bool string_generate(OutputIterator& sink, Char const* str)
|
||||
{
|
||||
return string_generate(sink, str, pass_through_filter());
|
||||
}
|
||||
|
||||
template <typename OutputIterator, typename Container>
|
||||
inline bool string_generate(OutputIterator& sink
|
||||
, Container const& c)
|
||||
{
|
||||
return string_generate(sink, c, pass_through_filter());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// generate a string given by a pointer, converting according using a
|
||||
// given character class and case tag
|
||||
template <typename OutputIterator, typename Char, typename CharEncoding
|
||||
, typename Tag>
|
||||
inline bool string_generate(OutputIterator& sink
|
||||
, Char const* str
|
||||
, CharEncoding, Tag)
|
||||
{
|
||||
return string_generate(sink, str, encoding_filter<CharEncoding, Tag>());
|
||||
}
|
||||
|
||||
template <typename OutputIterator, typename Container
|
||||
, typename CharEncoding, typename Tag>
|
||||
inline bool
|
||||
string_generate(OutputIterator& sink
|
||||
, Container const& c
|
||||
, CharEncoding, Tag)
|
||||
{
|
||||
return string_generate(sink, c, encoding_filter<CharEncoding, Tag>());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename OutputIterator, typename Char>
|
||||
inline bool string_generate(OutputIterator& sink
|
||||
, Char const* str
|
||||
, unused_type, unused_type)
|
||||
{
|
||||
return string_generate(sink, str);
|
||||
}
|
||||
|
||||
template <typename OutputIterator, typename Container>
|
||||
inline bool string_generate(OutputIterator& sink
|
||||
, Container const& c
|
||||
, unused_type, unused_type)
|
||||
{
|
||||
return string_generate(sink, c);
|
||||
}
|
||||
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
// 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_UNUSED_DELIMITER_MAR_15_2009_0923PM)
|
||||
#define BOOST_SPIRIT_KARMA_UNUSED_DELIMITER_MAR_15_2009_0923PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace karma { namespace detail
|
||||
{
|
||||
template <typename Delimiter>
|
||||
struct unused_delimiter : unused_type
|
||||
{
|
||||
unused_delimiter(Delimiter const& delim)
|
||||
: delimiter(delim) {}
|
||||
Delimiter const& delimiter;
|
||||
|
||||
private:
|
||||
// silence MSVC warning C4512: assignment operator could not be generated
|
||||
unused_delimiter& operator= (unused_delimiter const&);
|
||||
};
|
||||
|
||||
// If a surrounding verbatim[] directive was specified, the current
|
||||
// delimiter is of the type unused_delimiter. In this case we
|
||||
// re-activate the delimiter which was active before the verbatim[]
|
||||
// directive.
|
||||
template <typename Delimiter, typename Default>
|
||||
inline Delimiter const&
|
||||
get_delimiter(unused_delimiter<Delimiter> const& u, Default const&)
|
||||
{
|
||||
return u.delimiter;
|
||||
}
|
||||
|
||||
// If no surrounding verbatim[] directive was specified we activate
|
||||
// a single space as the delimiter to use.
|
||||
template <typename Delimiter, typename Default>
|
||||
inline Default const&
|
||||
get_delimiter(Delimiter const&, Default const& d)
|
||||
{
|
||||
return d;
|
||||
}
|
||||
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user