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

This commit is contained in:
2026-02-24 18:38:47 +00:00
parent da8c28aaeb
commit 65cb2619a7
13106 changed files with 2484322 additions and 1804 deletions
@@ -0,0 +1,165 @@
// Copyright (c) 2001-2011 Hartmut Kaiser
// Copyright (c) 2010 Bryce Lelbach
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#if !defined(SPIRIT_KARMA_AS_DEC_18_0510PM)
#define SPIRIT_KARMA_AS_DEC_18_0510PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/karma/meta_compiler.hpp>
#include <boost/spirit/home/karma/generator.hpp>
#include <boost/spirit/home/karma/domain.hpp>
#include <boost/spirit/home/karma/detail/output_iterator.hpp>
#include <boost/spirit/home/karma/detail/as.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/spirit/home/support/assert_msg.hpp>
#include <boost/spirit/home/support/container.hpp>
#include <boost/spirit/home/karma/detail/attributes.hpp>
namespace boost { namespace spirit { namespace karma
{
template <typename T>
struct as
: stateful_tag_type<T, tag::as>
{
BOOST_SPIRIT_ASSERT_MSG(
(traits::is_container<T>::type::value),
error_type_must_be_a_container,
(T));
};
}}}
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
// enables as_string[...]
template <>
struct use_directive<karma::domain, tag::as_string>
: mpl::true_ {};
// enables as_wstring[...]
template <>
struct use_directive<karma::domain, tag::as_wstring>
: mpl::true_ {};
// enables as<T>[...]
template <typename T>
struct use_directive<karma::domain, tag::stateful_tag<T, tag::as> >
: mpl::true_
{};
}}
namespace boost { namespace spirit { namespace karma
{
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::as_string;
using spirit::as_wstring;
#endif
using spirit::as_string_type;
using spirit::as_wstring_type;
///////////////////////////////////////////////////////////////////////////
// as_directive allows to hook custom conversions to string into the
// output generation process
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename T>
struct as_directive
: unary_generator<as_directive<Subject, T> >
{
typedef Subject subject_type;
typedef typename subject_type::properties properties;
as_directive(Subject const& subject)
: subject(subject) {}
template <typename Context, typename Iterator>
struct attribute
{
typedef T type;
};
template <typename OutputIterator, typename Context, typename Delimiter
, typename Attribute>
bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
, Attribute const& attr) const
{
if (!traits::valid_as<T>(attr))
return false;
return subject.generate(sink, ctx, d, traits::as<T>(attr)) &&
karma::delimit_out(sink, d); // always do post-delimiting
}
template <typename Context>
info what(Context& context) const
{
return info("as", subject.what(context));
}
Subject subject;
};
///////////////////////////////////////////////////////////////////////////
// Generator generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Modifiers>
struct make_directive<tag::as_string, Subject, Modifiers>
{
typedef as_directive<Subject, std::string> result_type;
result_type operator()(unused_type, Subject const& subject
, unused_type) const
{
return result_type(subject);
}
};
template <typename Subject, typename Modifiers>
struct make_directive<tag::as_wstring, Subject, Modifiers>
{
typedef as_directive<Subject, std::basic_string<wchar_t> > result_type;
result_type operator()(unused_type, Subject const& subject
, unused_type) const
{
return result_type(subject);
}
};
template <typename T, typename Subject, typename Modifiers>
struct make_directive<tag::stateful_tag<T, tag::as>, Subject, Modifiers>
{
typedef as_directive<Subject, T> result_type;
result_type operator()(unused_type, Subject const& subject
, unused_type) const
{
return result_type(subject);
}
};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename T>
struct has_semantic_action<karma::as_directive<Subject, T> >
: unary_has_semantic_action<Subject> {};
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename T, typename Attribute
, typename Context, typename Iterator>
struct handles_container<karma::as_directive<Subject, T>, Attribute
, Context, Iterator>
: mpl::false_ {}; // always dereference attribute if used in sequences
}}}
#endif
@@ -0,0 +1,132 @@
// 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_BUFFER_AUG_03_2009_0949AM)
#define SPIRIT_KARMA_BUFFER_AUG_03_2009_0949AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/karma/meta_compiler.hpp>
#include <boost/spirit/home/karma/generator.hpp>
#include <boost/spirit/home/karma/domain.hpp>
#include <boost/spirit/home/karma/detail/output_iterator.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/spirit/home/karma/detail/attributes.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_directive<karma::domain, tag::buffer> // enables buffer
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace karma
{
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::buffer;
#endif
using spirit::buffer_type;
///////////////////////////////////////////////////////////////////////////
// buffer_directive buffers all generated output of the embedded generator
// and flushes it only if the whole embedded generator succeeds
///////////////////////////////////////////////////////////////////////////
template <typename Subject>
struct buffer_directive : unary_generator<buffer_directive<Subject> >
{
typedef Subject subject_type;
typedef mpl::int_<
subject_type::properties::value |
generator_properties::countingbuffer
> properties;
buffer_directive(Subject const& subject)
: subject(subject) {}
template <typename Context, typename Iterator>
struct attribute
: traits::attribute_of<subject_type, Context, Iterator>
{};
template <typename OutputIterator, typename Context, typename Delimiter
, typename Attribute>
bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
, Attribute const& attr) const
{
// wrap the given output iterator to avoid output as long as the
// embedded generator (subject) fails
detail::enable_buffering<OutputIterator> buffering(sink);
bool r = false;
{
detail::disable_counting<OutputIterator> nocounting(sink);
r = subject.generate(sink, ctx, d, attr);
}
if (r)
buffering.buffer_copy();
return r;
}
template <typename Context>
info what(Context& context) const
{
return info("buffer", subject.what(context));
}
Subject subject;
};
///////////////////////////////////////////////////////////////////////////
// Generator generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Modifiers>
struct make_directive<tag::buffer, Subject, Modifiers>
{
typedef buffer_directive<Subject> result_type;
result_type operator()(unused_type, Subject const& subject
, unused_type) const
{
return result_type(subject);
}
};
// make sure buffer[buffer[...]] does not result in double buffering
template <typename Subject, typename Modifiers>
struct make_directive<tag::buffer, buffer_directive<Subject>, Modifiers>
{
typedef buffer_directive<Subject> result_type;
result_type operator()(unused_type
, buffer_directive<Subject> const& subject, unused_type) const
{
return subject;
}
};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Subject>
struct has_semantic_action<karma::buffer_directive<Subject> >
: unary_has_semantic_action<Subject> {};
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Attribute, typename Context
, typename Iterator>
struct handles_container<karma::buffer_directive<Subject>, Attribute
, Context, Iterator>
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
}}}
#endif
@@ -0,0 +1,335 @@
// 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_CENTER_ALIGNMENT_FEB_27_2007_1216PM)
#define BOOST_SPIRIT_KARMA_CENTER_ALIGNMENT_FEB_27_2007_1216PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/karma/meta_compiler.hpp>
#include <boost/spirit/home/karma/generator.hpp>
#include <boost/spirit/home/karma/domain.hpp>
#include <boost/spirit/home/karma/detail/output_iterator.hpp>
#include <boost/spirit/home/karma/detail/default_width.hpp>
#include <boost/spirit/home/karma/delimit_out.hpp>
#include <boost/spirit/home/karma/auxiliary/lazy.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/spirit/home/karma/detail/attributes.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/integer_traits.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/detail/workaround.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
// enables center[]
template <>
struct use_directive<karma::domain, tag::center>
: mpl::true_ {};
// enables center(d)[g] and center(w)[g], where d is a generator
// and w is a maximum width
template <typename T>
struct use_directive<karma::domain
, terminal_ex<tag::center, fusion::vector1<T> > >
: mpl::true_ {};
// enables *lazy* center(d)[g], where d provides a generator
template <>
struct use_lazy_directive<karma::domain, tag::center, 1>
: mpl::true_ {};
// enables center(w, d)[g], where d is a generator and w is a maximum
// width
template <typename Width, typename Padding>
struct use_directive<karma::domain
, terminal_ex<tag::center, fusion::vector2<Width, Padding> > >
: spirit::traits::matches<karma::domain, Padding> {};
// enables *lazy* center(w, d)[g], where d provides a generator and w is
// a maximum width
template <>
struct use_lazy_directive<karma::domain, tag::center, 2>
: mpl::true_ {};
}}
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace karma
{
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::center;
#endif
using spirit::center_type;
namespace detail
{
///////////////////////////////////////////////////////////////////////
// The center_generate template function is used for all the
// different flavors of the center[] directive.
///////////////////////////////////////////////////////////////////////
template <typename OutputIterator, typename Context, typename Delimiter,
typename Attribute, typename Embedded, typename Padding>
inline static bool
center_generate(OutputIterator& sink, Context& ctx,
Delimiter const& d, Attribute const& attr, Embedded const& e,
unsigned int const width, Padding const& p)
{
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
e; // suppresses warning: C4100: 'e' : unreferenced formal parameter
#endif
// wrap the given output iterator to allow left padding
detail::enable_buffering<OutputIterator> buffering(sink, width);
bool r = false;
// first generate the embedded output
{
detail::disable_counting<OutputIterator> nocounting(sink);
r = e.generate(sink, ctx, d, attr);
} // re-enable counting
buffering.disable(); // do not perform buffering any more
// generate the left padding
detail::enable_counting<OutputIterator> counting(sink);
std::size_t const pre = width - (buffering.buffer_size() + width)/2;
while (r && counting.count() < pre)
r = p.generate(sink, ctx, unused, unused);
if (r) {
// copy the embedded output to the target output iterator
buffering.buffer_copy();
// generate the right padding
while (r && counting.count() < width)
r = p.generate(sink, ctx, unused, unused);
}
return r;
}
}
///////////////////////////////////////////////////////////////////////////
// The simple left alignment directive is used for center[...]
// generators. It uses default values for the generated width (defined via
// the BOOST_KARMA_DEFAULT_FIELD_LENGTH constant) and for the padding
// generator (always spaces).
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Width = detail::default_width>
struct simple_center_alignment
: unary_generator<simple_center_alignment<Subject, Width> >
{
typedef Subject subject_type;
typedef mpl::int_<
generator_properties::countingbuffer | subject_type::properties::value
> properties;
template <typename Context, typename Iterator>
struct attribute
: traits::attribute_of<subject_type, Context, Iterator>
{};
simple_center_alignment(Subject const& subject, Width width = Width())
: subject(subject), width(width) {}
template <typename OutputIterator, typename Context, typename Delimiter
, typename Attribute>
bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
, Attribute const& attr) const
{
return detail::center_generate(sink, ctx, d, attr,
subject, width, compile<karma::domain>(' '));
}
template <typename Context>
info what(Context& context) const
{
return info("center", subject.what(context));
}
Subject subject;
Width width;
};
///////////////////////////////////////////////////////////////////////////
// The left alignment directive with padding, is used for generators like
// center(padding)[...], where padding is a arbitrary generator
// expression. It uses a default value for the generated width (defined
// via the BOOST_KARMA_DEFAULT_FIELD_LENGTH constant).
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Padding
, typename Width = detail::default_width>
struct padding_center_alignment
: unary_generator<padding_center_alignment<Subject, Padding, Width> >
{
typedef Subject subject_type;
typedef Padding padding_type;
typedef mpl::int_<
generator_properties::countingbuffer |
subject_type::properties::value | padding_type::properties::value
> properties;
template <typename Context, typename Iterator>
struct attribute
: traits::attribute_of<Subject, Context, Iterator>
{};
padding_center_alignment(Subject const& subject, Padding const& padding
, Width width = Width())
: subject(subject), padding(padding), width(width) {}
template <typename OutputIterator, typename Context, typename Delimiter
, typename Attribute>
bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
, Attribute const& attr) const
{
return detail::center_generate(sink, ctx, d, attr,
subject, width, padding);
}
template <typename Context>
info what(Context& context) const
{
return info("center", subject.what(context));
}
Subject subject;
Padding padding;
Width width;
};
///////////////////////////////////////////////////////////////////////////
// Generator generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
// creates center[] directive generator
template <typename Subject, typename Modifiers>
struct make_directive<tag::center, Subject, Modifiers>
{
typedef simple_center_alignment<Subject> result_type;
result_type operator()(unused_type, Subject const& subject
, unused_type) const
{
return result_type(subject);
}
};
// creates center(width)[] directive generator
template <typename Width, typename Subject, typename Modifiers>
struct make_directive<
terminal_ex<tag::center, fusion::vector1<Width> >
, Subject, Modifiers
, typename enable_if_c< integer_traits<Width>::is_integral >::type>
{
typedef simple_center_alignment<Subject, Width> result_type;
template <typename Terminal>
result_type operator()(Terminal const& term, Subject const& subject
, unused_type) const
{
return result_type(subject, fusion::at_c<0>(term.args));
}
};
// creates center(pad)[] directive generator
template <typename Padding, typename Subject, typename Modifiers>
struct make_directive<
terminal_ex<tag::center, fusion::vector1<Padding> >
, Subject, Modifiers
, typename enable_if<
mpl::and_<
spirit::traits::matches<karma::domain, Padding>,
mpl::not_<mpl::bool_<integer_traits<Padding>::is_integral> >
>
>::type>
{
typedef typename
result_of::compile<karma::domain, Padding, Modifiers>::type
padding_type;
typedef padding_center_alignment<Subject, padding_type> result_type;
template <typename Terminal>
result_type operator()(Terminal const& term, Subject const& subject
, Modifiers const& modifiers) const
{
return result_type(subject
, compile<karma::domain>(fusion::at_c<0>(term.args), modifiers));
}
};
// creates center(width, pad)[] directive generator
template <typename Width, typename Padding, typename Subject
, typename Modifiers>
struct make_directive<
terminal_ex<tag::center, fusion::vector2<Width, Padding> >
, Subject, Modifiers>
{
typedef typename
result_of::compile<karma::domain, Padding, Modifiers>::type
padding_type;
typedef padding_center_alignment<Subject, padding_type, Width> result_type;
template <typename Terminal>
result_type operator()(Terminal const& term, Subject const& subject
, Modifiers const& modifiers) const
{
return result_type(subject
, compile<karma::domain>(fusion::at_c<1>(term.args), modifiers)
, fusion::at_c<0>(term.args));
}
};
}}} // namespace boost::spirit::karma
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Width>
struct has_semantic_action<karma::simple_center_alignment<Subject, Width> >
: unary_has_semantic_action<Subject> {};
template <typename Subject, typename Padding, typename Width>
struct has_semantic_action<
karma::padding_center_alignment<Subject, Padding, Width> >
: unary_has_semantic_action<Subject> {};
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Width, typename Attribute
, typename Context, typename Iterator>
struct handles_container<
karma::simple_center_alignment<Subject, Width>, Attribute
, Context, Iterator>
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
template <typename Subject, typename Padding, typename Width
, typename Attribute, typename Context, typename Iterator>
struct handles_container<
karma::padding_center_alignment<Subject, Padding, Width>
, Attribute, Context, Iterator>
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
}}}
#endif
@@ -0,0 +1,293 @@
// 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_COLUMNS_DEC_03_2009_0736AM)
#define BOOST_SPIRIT_KARMA_COLUMNS_DEC_03_2009_0736AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/karma/meta_compiler.hpp>
#include <boost/spirit/home/karma/generator.hpp>
#include <boost/spirit/home/karma/domain.hpp>
#include <boost/spirit/home/karma/delimit_out.hpp>
#include <boost/spirit/home/karma/detail/default_width.hpp>
#include <boost/spirit/home/karma/auxiliary/eol.hpp>
#include <boost/spirit/home/karma/auxiliary/lazy.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/spirit/home/karma/detail/attributes.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/integer_traits.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_directive<karma::domain, tag::columns> // enables columns[]
: mpl::true_ {};
// enables columns(c)[g], where c provides the number of require columns
template <typename T>
struct use_directive<karma::domain
, terminal_ex<tag::columns, fusion::vector1<T> > >
: mpl::true_ {};
// enables *lazy* columns(c)[g]
template <>
struct use_lazy_directive<karma::domain, tag::columns, 1>
: mpl::true_ {};
// enables columns(c, d)[g], where c provides the number of require columns
// and d is the custom column-delimiter (default is karma::endl)
template <typename T1, typename T2>
struct use_directive<karma::domain
, terminal_ex<tag::columns, fusion::vector2<T1, T2> > >
: boost::spirit::traits::matches<karma::domain, T2> {};
// enables *lazy* columns(c, d)[g]
template <>
struct use_lazy_directive<karma::domain, tag::columns, 2>
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace karma
{
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::columns;
#endif
using spirit::columns_type;
namespace detail
{
template <typename Delimiter, typename ColumnDelimiter>
struct columns_delimiter
{
columns_delimiter(Delimiter const& delim
, ColumnDelimiter const& cdelim, unsigned int const numcols)
: delimiter(delim), column_delimiter(cdelim)
, numcolumns(numcols), count(0) {}
template <typename OutputIterator, typename Context
, typename Delimiter_, typename Attribute>
bool generate(OutputIterator& sink, Context&, Delimiter_ const&
, Attribute const&) const
{
// first invoke the embedded delimiter
if (!karma::delimit_out(sink, delimiter))
return false;
// now we count the number of invocations and emit the column
// delimiter if needed
if ((++count % numcolumns) == 0)
return karma::delimit_out(sink, column_delimiter);
return true;
}
// generate a final column delimiter if the last invocation didn't
// emit one
template <typename OutputIterator>
bool delimit_out(OutputIterator& sink) const
{
if (count % numcolumns)
return karma::delimit_out(sink, column_delimiter);
return true;
}
Delimiter const& delimiter;
ColumnDelimiter const& column_delimiter;
unsigned int const numcolumns;
mutable unsigned int count;
private:
// silence MSVC warning C4512: assignment operator could not be generated
columns_delimiter& operator= (columns_delimiter const&);
};
}
///////////////////////////////////////////////////////////////////////////
// The columns_generator is used for columns(c, d)[...] directives.
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename NumColumns, typename ColumnsDelimiter>
struct columns_generator
: unary_generator<columns_generator<Subject, NumColumns, ColumnsDelimiter> >
{
typedef Subject subject_type;
typedef ColumnsDelimiter delimiter_type;
typedef mpl::int_<
subject_type::properties::value | delimiter_type::properties::value
> properties;
template <typename Context, typename Iterator>
struct attribute
: traits::attribute_of<subject_type, Context, Iterator>
{};
columns_generator(Subject const& subject, NumColumns const& cols
, ColumnsDelimiter const& cdelimiter)
: subject(subject), numcolumns(cols), column_delimiter(cdelimiter)
{
// having zero number of columns doesn't make any sense
BOOST_ASSERT(numcolumns > 0);
}
template <typename OutputIterator, typename Context
, typename Delimiter, typename Attribute>
bool generate(OutputIterator& sink, Context& ctx
, Delimiter const& delimiter, Attribute const& attr) const
{
// The columns generator dispatches to the embedded generator
// while supplying a new delimiter to use, wrapping the outer
// delimiter.
typedef detail::columns_delimiter<
Delimiter, ColumnsDelimiter
> columns_delimiter_type;
columns_delimiter_type d(delimiter, column_delimiter, numcolumns);
return subject.generate(sink, ctx, d, attr) && d.delimit_out(sink);
}
template <typename Context>
info what(Context& context) const
{
return info("columns", subject.what(context));
}
Subject subject;
NumColumns numcolumns;
ColumnsDelimiter column_delimiter;
};
///////////////////////////////////////////////////////////////////////////
// Generator generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
// creates columns[] directive
template <typename Subject, typename Modifiers>
struct make_directive<tag::columns, Subject, Modifiers>
{
typedef typename
result_of::compile<karma::domain, eol_type, Modifiers>::type
columns_delimiter_type;
typedef columns_generator<
Subject, detail::default_columns, columns_delimiter_type>
result_type;
result_type operator()(unused_type, Subject const& subject
, unused_type) const
{
#if defined(BOOST_SPIRIT_NO_PREDEFINED_TERMINALS)
eol_type const eol = eol_type();
#endif
return result_type(subject, detail::default_columns()
, compile<karma::domain>(eol));
}
};
// creates columns(c)[] directive generator (c is the number of columns)
template <typename T, typename Subject, typename Modifiers>
struct make_directive<
terminal_ex<tag::columns, fusion::vector1<T> >
, Subject, Modifiers
, typename enable_if_c<integer_traits<T>::is_integral>::type>
{
typedef typename
result_of::compile<karma::domain, eol_type, Modifiers>::type
columns_delimiter_type;
typedef columns_generator<
Subject, T, columns_delimiter_type
> result_type;
template <typename Terminal>
result_type operator()(Terminal const& term, Subject const& subject
, unused_type) const
{
#if defined(BOOST_SPIRIT_NO_PREDEFINED_TERMINALS)
eol_type const eol = eol_type();
#endif
return result_type(subject, fusion::at_c<0>(term.args)
, compile<karma::domain>(eol));
}
};
// creates columns(d)[] directive generator (d is the column delimiter)
template <typename T, typename Subject, typename Modifiers>
struct make_directive<
terminal_ex<tag::columns, fusion::vector1<T> >
, Subject, Modifiers
, typename enable_if<
mpl::and_<
spirit::traits::matches<karma::domain, T>,
mpl::not_<mpl::bool_<integer_traits<T>::is_integral> >
>
>::type>
{
typedef typename
result_of::compile<karma::domain, T, Modifiers>::type
columns_delimiter_type;
typedef columns_generator<
Subject, detail::default_columns, columns_delimiter_type
> result_type;
template <typename Terminal>
result_type operator()(Terminal const& term, Subject const& subject
, unused_type) const
{
return result_type(subject, detail::default_columns()
, compile<karma::domain>(fusion::at_c<0>(term.args)));
}
};
// creates columns(c, d)[] directive generator (c is the number of columns
// and d is the column delimiter)
template <typename T1, typename T2, typename Subject, typename Modifiers>
struct make_directive<
terminal_ex<tag::columns, fusion::vector2<T1, T2> >
, Subject, Modifiers>
{
typedef typename
result_of::compile<karma::domain, T2, Modifiers>::type
columns_delimiter_type;
typedef columns_generator<
Subject, T1, columns_delimiter_type
> result_type;
template <typename Terminal>
result_type operator()(Terminal const& term, Subject const& subject
, unused_type) const
{
return result_type (subject, fusion::at_c<0>(term.args)
, compile<karma::domain>(fusion::at_c<1>(term.args)));
}
};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename T1, typename T2>
struct has_semantic_action<karma::columns_generator<Subject, T1, T2> >
: unary_has_semantic_action<Subject> {};
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename T1, typename T2, typename Attribute
, typename Context, typename Iterator>
struct handles_container<
karma::columns_generator<Subject, T1, T2>, Attribute
, Context, Iterator>
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
}}}
#endif
@@ -0,0 +1,200 @@
// 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_DELIMIT_MAR_02_2007_0217PM)
#define BOOST_SPIRIT_KARMA_DELIMIT_MAR_02_2007_0217PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/karma/meta_compiler.hpp>
#include <boost/spirit/home/karma/generator.hpp>
#include <boost/spirit/home/karma/domain.hpp>
#include <boost/spirit/home/karma/detail/unused_delimiter.hpp>
#include <boost/spirit/home/karma/delimit_out.hpp>
#include <boost/spirit/home/karma/auxiliary/lazy.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/spirit/home/karma/detail/attributes.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/fusion/include/vector.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_directive<karma::domain, tag::delimit> // enables delimit[]
: mpl::true_ {};
// enables delimit(d)[g], where d is a generator
template <typename T>
struct use_directive<karma::domain
, terminal_ex<tag::delimit, fusion::vector1<T> > >
: boost::spirit::traits::matches<karma::domain, T> {};
// enables *lazy* delimit(d)[g]
template <>
struct use_lazy_directive<karma::domain, tag::delimit, 1>
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace karma
{
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::delimit;
#endif
using spirit::delimit_type;
///////////////////////////////////////////////////////////////////////////
// The redelimit_generator generator is used for delimit[...] directives.
///////////////////////////////////////////////////////////////////////////
template <typename Subject>
struct redelimit_generator : unary_generator<redelimit_generator<Subject> >
{
typedef Subject subject_type;
typedef typename subject_type::properties properties;
template <typename Context, typename Iterator>
struct attribute
: traits::attribute_of<subject_type, Context, Iterator>
{};
redelimit_generator(Subject const& subject)
: subject(subject) {}
template <typename OutputIterator, typename Context, typename Delimiter
, typename Attribute>
bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
, Attribute const& attr) const
{
// The delimit_space generator simply dispatches to the embedded
// generator while supplying either the delimiter which has been
// used before a surrounding verbatim[] directive or a single
// space as the new delimiter to use (if no surrounding verbatim[]
// was specified).
return subject.generate(sink, ctx
, detail::get_delimiter(d, compile<karma::domain>(' ')), attr);
}
template <typename Context>
info what(Context& context) const
{
return info("delimit", subject.what(context));
}
Subject subject;
};
///////////////////////////////////////////////////////////////////////////
// The delimit_generator is used for delimit(d)[...] directives.
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Delimiter>
struct delimit_generator
: unary_generator<delimit_generator<Subject, Delimiter> >
{
typedef Subject subject_type;
typedef Delimiter delimiter_type;
typedef typename subject_type::properties properties;
template <typename Context, typename Iterator>
struct attribute
: traits::attribute_of<subject_type, Context, Iterator>
{};
delimit_generator(Subject const& subject, Delimiter const& delimiter)
: subject(subject), delimiter(delimiter) {}
template <typename OutputIterator, typename Context
, typename Delimiter_, typename Attribute>
bool generate(OutputIterator& sink, Context& ctx, Delimiter_ const&
, Attribute const& attr) const
{
// the delimit generator simply dispatches to the embedded
// generator while supplying it's argument as the new delimiter
// to use
return subject.generate(sink, ctx, delimiter, attr);
}
template <typename Context>
info what(Context& context) const
{
return info("delimit", subject.what(context));
}
Subject subject;
Delimiter delimiter;
};
///////////////////////////////////////////////////////////////////////////
// Generator generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Modifiers>
struct make_directive<tag::delimit, Subject, Modifiers>
{
typedef redelimit_generator<Subject> result_type;
result_type operator()(unused_type, Subject const& subject
, unused_type) const
{
return result_type(subject);
}
};
template <typename Delimiter, typename Subject, typename Modifiers>
struct make_directive<
terminal_ex<tag::delimit, fusion::vector1<Delimiter> >
, Subject, Modifiers>
{
typedef typename
result_of::compile<karma::domain, Delimiter, Modifiers>::type
delimiter_type;
typedef delimit_generator<Subject, delimiter_type> result_type;
template <typename Terminal>
result_type operator()(Terminal const& term, Subject const& subject
, unused_type) const
{
return result_type(subject
, compile<karma::domain>(fusion::at_c<0>(term.args)));
}
};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Subject>
struct has_semantic_action<karma::redelimit_generator<Subject> >
: unary_has_semantic_action<Subject> {};
template <typename Subject, typename Delimiter>
struct has_semantic_action<karma::delimit_generator<Subject, Delimiter> >
: unary_has_semantic_action<Subject> {};
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Attribute
, typename Context, typename Iterator>
struct handles_container<karma::redelimit_generator<Subject>, Attribute
, Context, Iterator>
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
template <typename Subject, typename Delimiter, typename Attribute
, typename Context, typename Iterator>
struct handles_container<karma::delimit_generator<Subject, Delimiter>
, Attribute, Context, Iterator>
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
}}}
#endif
@@ -0,0 +1,230 @@
// 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_DUPLICATE_JUL_11_2010_0954AM)
#define SPIRIT_KARMA_DUPLICATE_JUL_11_2010_0954AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/karma/meta_compiler.hpp>
#include <boost/spirit/home/karma/generator.hpp>
#include <boost/spirit/home/karma/domain.hpp>
#include <boost/spirit/home/karma/detail/attributes.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/assert_msg.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/fusion/include/cons.hpp>
#include <boost/fusion/include/make_cons.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/at_c.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/bool.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_directive<karma::domain, tag::duplicate> // enables duplicate
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace karma
{
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::duplicate;
#endif
using spirit::duplicate_type;
///////////////////////////////////////////////////////////////////////////
namespace detail
{
///////////////////////////////////////////////////////////////////////
template <typename T
, bool IsSequence = fusion::traits::is_sequence<T>::value>
struct attribute_count
: fusion::result_of::size<T>
{};
template <>
struct attribute_count<unused_type, false>
: mpl::int_<0>
{};
template <typename T>
struct attribute_count<T, false>
: mpl::int_<1>
{};
///////////////////////////////////////////////////////////////////////
template <typename T
, bool IsSequence = fusion::traits::is_sequence<T>::value>
struct first_attribute_of_subject
: remove_reference<typename fusion::result_of::at_c<T, 0>::type>
{};
template <typename T>
struct first_attribute_of_subject<T, false>
: mpl::identity<T>
{};
template <typename T, typename Context, typename Iterator>
struct first_attribute_of
: first_attribute_of_subject<
typename traits::attribute_of<T, Context, Iterator>::type>
{};
///////////////////////////////////////////////////////////////////////
template <typename Attribute, typename T, int N>
struct duplicate_sequence_attribute
{
typedef typename fusion::result_of::make_cons<
reference_wrapper<T const>
, typename duplicate_sequence_attribute<Attribute, T, N-1>::type
>::type type;
static type call(T const& t)
{
return fusion::make_cons(boost::cref(t)
, duplicate_sequence_attribute<Attribute, T, N-1>::call(t));
}
};
template <typename Attribute, typename T>
struct duplicate_sequence_attribute<Attribute, T, 1>
{
typedef typename fusion::result_of::make_cons<
reference_wrapper<T const> >::type type;
static type call(T const& t)
{
return fusion::make_cons(boost::cref(t));
}
};
///////////////////////////////////////////////////////////////////////
template <typename Attribute, typename T
, int N = attribute_count<Attribute>::value
, bool IsSequence = fusion::traits::is_sequence<Attribute>::value>
struct duplicate_attribute
{
BOOST_SPIRIT_ASSERT_MSG(N > 0, invalid_duplication_count, (Attribute));
typedef typename duplicate_sequence_attribute<Attribute, T, N>::type
cons_type;
typedef typename fusion::result_of::as_vector<cons_type>::type type;
static type call(T const& t)
{
return fusion::as_vector(
duplicate_sequence_attribute<Attribute, T, N>::call(t));
}
};
template <typename Attribute, typename T>
struct duplicate_attribute<Attribute, T, 0, false>
{
typedef unused_type type;
static type call(T const&)
{
return unused;
}
};
template <typename Attribute, typename T, int N>
struct duplicate_attribute<Attribute, T, N, false>
{
typedef Attribute const& type;
static type call(T const& t)
{
return t;
}
};
}
template <typename Attribute, typename T>
inline typename detail::duplicate_attribute<Attribute, T>::type
duplicate_attribute(T const& t)
{
return detail::duplicate_attribute<Attribute, T>::call(t);
}
///////////////////////////////////////////////////////////////////////////
// duplicate_directive duplicate its attribute for all elements of the
// subject generator without generating anything itself
///////////////////////////////////////////////////////////////////////////
template <typename Subject>
struct duplicate_directive : unary_generator<duplicate_directive<Subject> >
{
typedef Subject subject_type;
typedef typename subject_type::properties properties;
duplicate_directive(Subject const& subject)
: subject(subject) {}
template <typename Context, typename Iterator = unused_type>
struct attribute
: detail::first_attribute_of<Subject, Context, Iterator>
{};
template <typename OutputIterator, typename Context, typename Delimiter
, typename Attribute>
bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
, Attribute const& attr) const
{
typedef typename traits::attribute_of<Subject, Context>::type
subject_attr_type;
return subject.generate(sink, ctx, d
, duplicate_attribute<subject_attr_type>(attr));
}
template <typename Context>
info what(Context& context) const
{
return info("duplicate", subject.what(context));
}
Subject subject;
};
///////////////////////////////////////////////////////////////////////////
// Generator generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Modifiers>
struct make_directive<tag::duplicate, Subject, Modifiers>
{
typedef duplicate_directive<Subject> result_type;
result_type operator()(unused_type, Subject const& subject
, unused_type) const
{
return result_type(subject);
}
};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Subject>
struct has_semantic_action<karma::duplicate_directive<Subject> >
: unary_has_semantic_action<Subject> {};
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Attribute, typename Context
, typename Iterator>
struct handles_container<karma::duplicate_directive<Subject>, Attribute
, Context, Iterator>
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
}}}
#endif
@@ -0,0 +1,35 @@
// Copyright (c) 2001-2011 Joel de Guzman
// 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_ENCODING_MARCH_05_2010_0550PM)
#define SPIRIT_KARMA_ENCODING_MARCH_05_2010_0550PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/karma/meta_compiler.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
// enables encoding
template <typename CharEncoding>
struct use_directive<
karma::domain, tag::char_code<tag::encoding, CharEncoding> >
: mpl::true_ {};
template <typename CharEncoding>
struct is_modifier_directive<
karma::domain, tag::char_code<tag::encoding, CharEncoding> >
: mpl::true_ {};
}}
#endif
@@ -0,0 +1,318 @@
// 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_LEFT_ALIGNMENT_FEB_27_2007_1216PM)
#define BOOST_SPIRIT_KARMA_LEFT_ALIGNMENT_FEB_27_2007_1216PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/karma/meta_compiler.hpp>
#include <boost/spirit/home/karma/generator.hpp>
#include <boost/spirit/home/karma/domain.hpp>
#include <boost/spirit/home/karma/detail/output_iterator.hpp>
#include <boost/spirit/home/karma/detail/default_width.hpp>
#include <boost/spirit/home/karma/delimit_out.hpp>
#include <boost/spirit/home/karma/auxiliary/lazy.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/karma/detail/attributes.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/integer_traits.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/detail/workaround.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
// enables left_align[]
template <>
struct use_directive<karma::domain, tag::left_align>
: mpl::true_ {};
// enables left_align(d)[g] and left_align(w)[g], where d is a generator
// and w is a maximum width
template <typename T>
struct use_directive<karma::domain
, terminal_ex<tag::left_align, fusion::vector1<T> > >
: mpl::true_ {};
// enables *lazy* left_align(d)[g], where d provides a generator
template <>
struct use_lazy_directive<karma::domain, tag::left_align, 1>
: mpl::true_ {};
// enables left_align(w, d)[g], where d is a generator and w is a maximum
// width
template <typename Width, typename Padding>
struct use_directive<karma::domain
, terminal_ex<tag::left_align, fusion::vector2<Width, Padding> > >
: spirit::traits::matches<karma::domain, Padding> {};
// enables *lazy* left_align(w, d)[g], where d provides a generator and w
// is a maximum width
template <>
struct use_lazy_directive<karma::domain, tag::left_align, 2>
: mpl::true_ {};
}}
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace karma
{
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::left_align;
#endif
using spirit::left_align_type;
namespace detail
{
///////////////////////////////////////////////////////////////////////
// The left_align_generate template function is used for all the
// different flavors of the left_align[] directive.
///////////////////////////////////////////////////////////////////////
template <typename OutputIterator, typename Context, typename Delimiter,
typename Attribute, typename Embedded, typename Padding>
inline static bool
left_align_generate(OutputIterator& sink, Context& ctx,
Delimiter const& d, Attribute const& attr, Embedded const& e,
unsigned int const width, Padding const& p)
{
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
e; // suppresses warning: C4100: 'e' : unreferenced formal parameter
#endif
// wrap the given output iterator to allow counting
detail::enable_counting<OutputIterator> counting(sink);
// first generate the underlying output
bool r = e.generate(sink, ctx, d, attr);
// pad the output until the max width is reached
while(r && counting.count() < width)
r = p.generate(sink, ctx, unused, unused);
return r;
}
}
///////////////////////////////////////////////////////////////////////////
// The simple left alignment directive is used for left_align[...]
// generators. It uses default values for the generated width (defined via
// the BOOST_KARMA_DEFAULT_FIELD_LENGTH constant) and for the padding
// generator (always spaces).
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Width = detail::default_width>
struct simple_left_alignment
: unary_generator<simple_left_alignment<Subject, Width> >
{
typedef Subject subject_type;
typedef mpl::int_<
generator_properties::counting | subject_type::properties::value
> properties;
template <typename Context, typename Iterator>
struct attribute
: traits::attribute_of<subject_type, Context, Iterator>
{};
simple_left_alignment(Subject const& subject, Width width = Width())
: subject(subject), width(width) {}
template <typename OutputIterator, typename Context, typename Delimiter
, typename Attribute>
bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
, Attribute const& attr) const
{
return detail::left_align_generate(sink, ctx, d, attr,
subject, width, compile<karma::domain>(' '));
}
template <typename Context>
info what(Context& context) const
{
return info("left_align", subject.what(context));
}
Subject subject;
Width width;
};
///////////////////////////////////////////////////////////////////////////
// The left alignment directive with padding, is used for generators like
// left_align(padding)[...], where padding is a arbitrary generator
// expression. It uses a default value for the generated width (defined
// via the BOOST_KARMA_DEFAULT_FIELD_LENGTH constant).
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Padding
, typename Width = detail::default_width>
struct padding_left_alignment
: unary_generator<padding_left_alignment<Subject, Padding, Width> >
{
typedef Subject subject_type;
typedef Padding padding_type;
typedef mpl::int_<
generator_properties::counting |
subject_type::properties::value | padding_type::properties::value
> properties;
template <typename Context, typename Iterator>
struct attribute
: traits::attribute_of<subject_type, Context, Iterator>
{};
padding_left_alignment(Subject const& subject, Padding const& padding
, Width width = Width())
: subject(subject), padding(padding), width(width) {}
template <typename OutputIterator, typename Context, typename Delimiter
, typename Attribute>
bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
, Attribute const& attr) const
{
return detail::left_align_generate(sink, ctx, d, attr,
subject, width, padding);
}
template <typename Context>
info what(Context& context) const
{
return info("left_align", subject.what(context));
}
Subject subject;
Padding padding;
Width width;
};
///////////////////////////////////////////////////////////////////////////
// Generator generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
// creates left_align[] directive generator
template <typename Subject, typename Modifiers>
struct make_directive<tag::left_align, Subject, Modifiers>
{
typedef simple_left_alignment<Subject> result_type;
result_type operator()(unused_type, Subject const& subject
, unused_type) const
{
return result_type(subject);
}
};
// creates left_align(width)[] directive generator
template <typename Width, typename Subject, typename Modifiers>
struct make_directive<
terminal_ex<tag::left_align, fusion::vector1<Width> >
, Subject, Modifiers
, typename enable_if_c< integer_traits<Width>::is_integral >::type>
{
typedef simple_left_alignment<Subject, Width> result_type;
template <typename Terminal>
result_type operator()(Terminal const& term, Subject const& subject
, unused_type) const
{
return result_type(subject, fusion::at_c<0>(term.args));
}
};
// creates left_align(pad)[] directive generator
template <typename Padding, typename Subject, typename Modifiers>
struct make_directive<
terminal_ex<tag::left_align, fusion::vector1<Padding> >
, Subject, Modifiers
, typename enable_if<
mpl::and_<
spirit::traits::matches<karma::domain, Padding>,
mpl::not_<mpl::bool_<integer_traits<Padding>::is_integral> >
>
>::type>
{
typedef typename
result_of::compile<karma::domain, Padding, Modifiers>::type
padding_type;
typedef padding_left_alignment<Subject, padding_type> result_type;
template <typename Terminal>
result_type operator()(Terminal const& term, Subject const& subject
, Modifiers const& modifiers) const
{
return result_type(subject
, compile<karma::domain>(fusion::at_c<0>(term.args), modifiers));
}
};
// creates left_align(width, pad)[] directive generator
template <typename Width, typename Padding, typename Subject
, typename Modifiers>
struct make_directive<
terminal_ex<tag::left_align, fusion::vector2<Width, Padding> >
, Subject, Modifiers>
{
typedef typename
result_of::compile<karma::domain, Padding, Modifiers>::type
padding_type;
typedef padding_left_alignment<Subject, padding_type, Width> result_type;
template <typename Terminal>
result_type operator()(Terminal const& term, Subject const& subject
, Modifiers const& modifiers) const
{
return result_type(subject
, compile<karma::domain>(fusion::at_c<1>(term.args), modifiers)
, fusion::at_c<0>(term.args));
}
};
}}} // namespace boost::spirit::karma
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Width>
struct has_semantic_action<karma::simple_left_alignment<Subject, Width> >
: unary_has_semantic_action<Subject> {};
template <typename Subject, typename Padding, typename Width>
struct has_semantic_action<
karma::padding_left_alignment<Subject, Padding, Width> >
: unary_has_semantic_action<Subject> {};
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Width, typename Attribute
, typename Context, typename Iterator>
struct handles_container<
karma::simple_left_alignment<Subject, Width>, Attribute
, Context, Iterator>
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
template <typename Subject, typename Padding, typename Width
, typename Attribute, typename Context, typename Iterator>
struct handles_container<
karma::padding_left_alignment<Subject, Padding, Width>
, Attribute, Context, Iterator>
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
}}}
#endif
@@ -0,0 +1,246 @@
// 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_MAXWIDTH_MAR_18_2009_0827AM)
#define BOOST_SPIRIT_KARMA_MAXWIDTH_MAR_18_2009_0827AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/karma/meta_compiler.hpp>
#include <boost/spirit/home/karma/generator.hpp>
#include <boost/spirit/home/karma/domain.hpp>
#include <boost/spirit/home/karma/detail/output_iterator.hpp>
#include <boost/spirit/home/karma/detail/default_width.hpp>
#include <boost/spirit/home/karma/delimit_out.hpp>
#include <boost/spirit/home/karma/auxiliary/lazy.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/spirit/home/karma/detail/attributes.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/detail/workaround.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
// enables maxwidth[]
template <>
struct use_directive<karma::domain, tag::maxwidth>
: mpl::true_ {};
// enables maxwidth(w)[g], where w provides a maxwidth
template <typename T>
struct use_directive<karma::domain
, terminal_ex<tag::maxwidth, fusion::vector1<T> > >
: mpl::true_ {};
// enables *lazy* maxwidth(w)[g], where w provides a maxwidth
template <>
struct use_lazy_directive<karma::domain, tag::maxwidth, 1>
: mpl::true_ {};
// enables maxwidth(w, r)[g], where w provides a maxwidth and r is an output
// iterator used to receive the rest of the output not fitting into the
// maxwidth limit
template <typename T, typename RestIter>
struct use_directive<karma::domain
, terminal_ex<tag::maxwidth, fusion::vector2<T, RestIter> > >
: mpl::true_ {};
// enables *lazy* maxwidth(w, r)[g], where w provides a maxwidth and r is
// an output iterator used to receive the rest of the output not fitting
// into the maxwidth limit
template <>
struct use_lazy_directive<karma::domain, tag::maxwidth, 2>
: mpl::true_ {};
}}
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace karma
{
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::maxwidth;
#endif
using spirit::maxwidth_type;
namespace detail
{
///////////////////////////////////////////////////////////////////////
template <typename OutputIterator, typename RestIterator>
bool buffer_copy_rest(detail::enable_buffering<OutputIterator>& buff
, std::size_t start_at, RestIterator& dest)
{
return buff.buffer_copy_rest(dest, start_at);
}
template <typename OutputIterator>
bool buffer_copy_rest(detail::enable_buffering<OutputIterator>&
, std::size_t, unused_type)
{
return true;
}
///////////////////////////////////////////////////////////////////////
// The maxwidth_generate template function is used for all the
// different flavors of the maxwidth[] directive.
///////////////////////////////////////////////////////////////////////
template <typename OutputIterator, typename Context, typename Delimiter,
typename Attribute, typename Embedded, typename Rest>
inline static bool
maxwidth_generate(OutputIterator& sink, Context& ctx,
Delimiter const& d, Attribute const& attr, Embedded const& e,
unsigned int const maxwidth, Rest& restdest)
{
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
e; // suppresses warning: C4100: 'e' : unreferenced formal parameter
#endif
// wrap the given output iterator to allow buffering, but disable
// counting
detail::enable_buffering<OutputIterator> buffering(sink);
// generate the underlying output and copy the embedded
// output to the target output iterator applying the given
// maxwidth
bool r = false;
{
detail::disable_counting<OutputIterator> nocounting(sink);
r = e.generate(sink, ctx, d, attr);
} // re-enable counting
return r && buffering.buffer_copy(maxwidth) &&
buffer_copy_rest(buffering, maxwidth, restdest);
}
}
///////////////////////////////////////////////////////////////////////////
// The maxwidth directive is used for maxwidth[...]
// generators. It uses default values for the generated width (defined via
// the BOOST_KARMA_DEFAULT_FIELD_MAXWIDTH constant).
//
// The maxwidth with width directive, is used for generators
// like maxwidth(width)[...].
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Width = detail::default_max_width
, typename Rest = unused_type>
struct maxwidth_width
: unary_generator<maxwidth_width<Subject, Width, Rest> >
{
typedef Subject subject_type;
typedef mpl::int_<
generator_properties::countingbuffer | subject_type::properties::value
> properties;
template <typename Context, typename Iterator>
struct attribute
: traits::attribute_of<subject_type, Context, Iterator>
{};
maxwidth_width(Subject const& subject, Width const& w = Width()
, Rest const& r = Rest())
: subject(subject), width(w), rest(r) {}
template <typename OutputIterator, typename Context, typename Delimiter
, typename Attribute>
bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
, Attribute const& attr) const
{
return detail::maxwidth_generate(sink, ctx, d, attr, subject
, width, rest);
}
template <typename Context>
info what(Context& context) const
{
return info("maxwidth", subject.what(context));
}
Subject subject;
Width width;
Rest rest;
};
///////////////////////////////////////////////////////////////////////////
// Generator generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
// creates maxwidth[] directive generator
template <typename Subject, typename Modifiers>
struct make_directive<tag::maxwidth, Subject, Modifiers>
{
typedef maxwidth_width<Subject> result_type;
result_type operator()(unused_type, Subject const& subject
, unused_type) const
{
return result_type(subject);
}
};
// creates maxwidth(width)[] directive generator
template <typename T, typename Subject, typename Modifiers>
struct make_directive<
terminal_ex<tag::maxwidth, fusion::vector1<T> >
, Subject, Modifiers>
{
typedef maxwidth_width<Subject, T> result_type;
template <typename Terminal>
result_type operator()(Terminal const& term, Subject const& subject
, unused_type) const
{
return result_type(subject, fusion::at_c<0>(term.args), unused);
}
};
// creates maxwidth(width, restiter)[] directive generator
template <
typename T, typename RestIter, typename Subject, typename Modifiers>
struct make_directive<
terminal_ex<tag::maxwidth, fusion::vector2<T, RestIter> >
, Subject, Modifiers>
{
typedef maxwidth_width<Subject, T, RestIter> result_type;
template <typename Terminal>
result_type operator()(Terminal const& term, Subject const& subject
, unused_type) const
{
return result_type(subject, fusion::at_c<0>(term.args)
, fusion::at_c<1>(term.args));
}
};
}}} // namespace boost::spirit::karma
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Width, typename Rest>
struct has_semantic_action<karma::maxwidth_width<Subject, Width, Rest> >
: unary_has_semantic_action<Subject> {};
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Attribute, typename Context
, typename Iterator>
struct handles_container<karma::maxwidth_width<Subject>, Attribute
, Context, Iterator>
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
}}}
#endif
@@ -0,0 +1,116 @@
// 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_NO_DELIMIT_JAN_19_2010_0920AM)
#define BOOST_SPIRIT_KARMA_NO_DELIMIT_JAN_19_2010_0920AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/karma/meta_compiler.hpp>
#include <boost/spirit/home/karma/generator.hpp>
#include <boost/spirit/home/karma/domain.hpp>
#include <boost/spirit/home/karma/detail/unused_delimiter.hpp>
#include <boost/spirit/home/karma/auxiliary/lazy.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/spirit/home/karma/detail/attributes.hpp>
#include <boost/spirit/home/support/info.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_directive<karma::domain, tag::no_delimit> // enables no_delimit[]
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace karma
{
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::no_delimit;
#endif
using spirit::no_delimit_type;
///////////////////////////////////////////////////////////////////////////
// The no_delimit generator is used for no_delimit[...] directives.
///////////////////////////////////////////////////////////////////////////
template <typename Subject>
struct no_delimit_generator
: unary_generator<no_delimit_generator<Subject> >
{
typedef Subject subject_type;
typedef typename subject_type::properties properties;
template <typename Context, typename Iterator>
struct attribute
: traits::attribute_of<subject_type, Context, Iterator>
{};
no_delimit_generator(Subject const& subject)
: subject(subject) {}
template <typename OutputIterator, typename Context, typename Delimiter
, typename Attribute>
bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
, Attribute const& attr) const
{
// the no_delimit generator simply dispatches to the embedded
// generator while supplying unused_delimiter as the new delimiter
// to avoid delimiting down the generator stream
typedef detail::unused_delimiter<Delimiter> unused_delimiter;
// the difference to verbatim[] is that this does not post-delimit
return subject.generate(sink, ctx, unused_delimiter(d), attr);
}
template <typename Context>
info what(Context& context) const
{
return info("no_delimit", subject.what(context));
}
Subject subject;
};
///////////////////////////////////////////////////////////////////////////
// Generator generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Modifiers>
struct make_directive<tag::no_delimit, Subject, Modifiers>
{
typedef no_delimit_generator<Subject> result_type;
result_type
operator()(unused_type, Subject const& subject, unused_type) const
{
return result_type(subject);
}
};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Subject>
struct has_semantic_action<karma::no_delimit_generator<Subject> >
: unary_has_semantic_action<Subject> {};
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Attribute, typename Context
, typename Iterator>
struct handles_container<karma::no_delimit_generator<Subject>, Attribute
, Context, Iterator>
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
}}}
#endif
@@ -0,0 +1,135 @@
// 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_OMIT_JUL_20_2009_1008AM)
#define SPIRIT_KARMA_OMIT_JUL_20_2009_1008AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/karma/meta_compiler.hpp>
#include <boost/spirit/home/karma/generator.hpp>
#include <boost/spirit/home/karma/domain.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/spirit/home/karma/detail/attributes.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_directive<karma::domain, tag::omit> // enables omit
: mpl::true_ {};
template <>
struct use_directive<karma::domain, tag::skip> // enables skip
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace karma
{
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::omit;
using spirit::skip;
#endif
using spirit::omit_type;
using spirit::skip_type;
///////////////////////////////////////////////////////////////////////////
// omit_directive consumes the attribute of subject generator without
// generating anything
///////////////////////////////////////////////////////////////////////////
template <typename Subject, bool Execute>
struct omit_directive : unary_generator<omit_directive<Subject, Execute> >
{
typedef Subject subject_type;
typedef mpl::int_<
generator_properties::disabling | subject_type::properties::value
> properties;
omit_directive(Subject const& subject)
: subject(subject) {}
template <typename Context, typename Iterator = unused_type>
struct attribute
: traits::attribute_of<subject_type, Context, Iterator>
{};
template <typename OutputIterator, typename Context, typename Delimiter
, typename Attribute>
bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
, Attribute const& attr) const
{
// We need to actually compile the output operation as we don't
// have any other means to verify, whether the passed attribute is
// compatible with the subject.
// omit[] will execute the code, while skip[] doesn't execute it
if (Execute) {
// wrap the given output iterator to avoid output
detail::disable_output<OutputIterator> disable(sink);
return subject.generate(sink, ctx, d, attr);
}
return true;
}
template <typename Context>
info what(Context& context) const
{
return info(Execute ? "omit" : "skip", subject.what(context));
}
Subject subject;
};
///////////////////////////////////////////////////////////////////////////
// Generator generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Modifiers>
struct make_directive<tag::omit, Subject, Modifiers>
{
typedef omit_directive<Subject, true> result_type;
result_type operator()(unused_type, Subject const& subject
, unused_type) const
{
return result_type(subject);
}
};
template <typename Subject, typename Modifiers>
struct make_directive<tag::skip, Subject, Modifiers>
{
typedef omit_directive<Subject, false> result_type;
result_type operator()(unused_type, Subject const& subject
, unused_type) const
{
return result_type(subject);
}
};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Subject, bool Execute>
struct has_semantic_action<karma::omit_directive<Subject, Execute> >
: unary_has_semantic_action<Subject> {};
///////////////////////////////////////////////////////////////////////////
template <typename Subject, bool Execute, typename Attribute
, typename Context, typename Iterator>
struct handles_container<karma::omit_directive<Subject, Execute>, Attribute
, Context, Iterator>
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
}}}
#endif
@@ -0,0 +1,397 @@
// 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_REPEAT_MAY_18_2009_0926AM)
#define SPIRIT_KARMA_REPEAT_MAY_18_2009_0926AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/karma/meta_compiler.hpp>
#include <boost/spirit/home/karma/detail/output_iterator.hpp>
#include <boost/spirit/home/karma/detail/get_stricttag.hpp>
#include <boost/spirit/home/karma/generator.hpp>
#include <boost/spirit/home/karma/auxiliary/lazy.hpp>
#include <boost/spirit/home/karma/operator/kleene.hpp>
#include <boost/spirit/home/support/container.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/spirit/home/karma/detail/attributes.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/fusion/include/at.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_directive<karma::domain, tag::repeat> // enables repeat[p]
: mpl::true_ {};
template <typename T>
struct use_directive<karma::domain
, terminal_ex<tag::repeat // enables repeat(exact)[p]
, fusion::vector1<T> >
> : mpl::true_ {};
template <typename T>
struct use_directive<karma::domain
, terminal_ex<tag::repeat // enables repeat(min, max)[p]
, fusion::vector2<T, T> >
> : mpl::true_ {};
template <typename T>
struct use_directive<karma::domain
, terminal_ex<tag::repeat // enables repeat(min, inf)[p]
, fusion::vector2<T, inf_type> >
> : mpl::true_ {};
template <> // enables *lazy* repeat(exact)[p]
struct use_lazy_directive<
karma::domain
, tag::repeat
, 1 // arity
> : mpl::true_ {};
template <> // enables *lazy* repeat(min, max)[p]
struct use_lazy_directive< // and repeat(min, inf)[p]
karma::domain
, tag::repeat
, 2 // arity
> : mpl::true_ {};
}}
namespace boost { namespace spirit { namespace karma
{
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::repeat;
using spirit::inf;
#endif
using spirit::repeat_type;
using spirit::inf_type;
///////////////////////////////////////////////////////////////////////////
// handles repeat(exact)[p]
template <typename T>
struct exact_iterator
{
exact_iterator(T const exact)
: exact(exact) {}
typedef T type;
T start() const { return 0; }
bool got_max(T i) const { return i >= exact; }
bool got_min(T i) const { return i >= exact; }
T const exact;
private:
// silence MSVC warning C4512: assignment operator could not be generated
exact_iterator& operator= (exact_iterator const&);
};
// handles repeat(min, max)[p]
template <typename T>
struct finite_iterator
{
finite_iterator(T const min, T const max)
: min BOOST_PREVENT_MACRO_SUBSTITUTION (min)
, max BOOST_PREVENT_MACRO_SUBSTITUTION (max) {}
typedef T type;
T start() const { return 0; }
bool got_max(T i) const { return i >= max; }
bool got_min(T i) const { return i >= min; }
T const min;
T const max;
private:
// silence MSVC warning C4512: assignment operator could not be generated
finite_iterator& operator= (finite_iterator const&);
};
// handles repeat(min, inf)[p]
template <typename T>
struct infinite_iterator
{
infinite_iterator(T const min)
: min BOOST_PREVENT_MACRO_SUBSTITUTION (min) {}
typedef T type;
T start() const { return 0; }
bool got_max(T /*i*/) const { return false; }
bool got_min(T i) const { return i >= min; }
T const min;
private:
// silence MSVC warning C4512: assignment operator could not be generated
infinite_iterator& operator= (infinite_iterator const&);
};
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename LoopIter, typename Strict
, typename Derived>
struct base_repeat_generator : unary_generator<Derived>
{
private:
// iterate over the given container until its exhausted or the embedded
// generator succeeds
template <typename F, typename Attribute>
bool generate_subject(F f, Attribute const&, mpl::false_) const
{
// Failing subject generators are just skipped. This allows to
// selectively generate items in the provided attribute.
while (!f.is_at_end())
{
bool r = !f(subject);
if (r)
return true;
if (!f.is_at_end())
f.next();
}
return false;
}
template <typename F, typename Attribute>
bool generate_subject(F f, Attribute const&, mpl::true_) const
{
return !f(subject);
}
// There is no way to distinguish a failed generator from a
// generator to be skipped. We assume the user takes responsibility
// for ending the loop if no attribute is specified.
template <typename F>
bool generate_subject(F f, unused_type, mpl::false_) const
{
return !f(subject);
}
public:
typedef Subject subject_type;
typedef mpl::int_<subject_type::properties::value> properties;
// Build a std::vector from the subject's attribute. Note
// that build_std_vector may return unused_type if the
// subject's attribute is an unused_type.
template <typename Context, typename Iterator>
struct attribute
: traits::build_std_vector<
typename traits::attribute_of<Subject, Context, Iterator>::type
>
{};
base_repeat_generator(Subject const& subject, LoopIter const& iter)
: subject(subject), iter(iter) {}
template <typename OutputIterator, typename Context, typename Delimiter
, typename Attribute>
bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
, Attribute const& attr) const
{
typedef detail::fail_function<
OutputIterator, Context, Delimiter
> fail_function;
typedef typename traits::container_iterator<
typename add_const<Attribute>::type
>::type iterator_type;
typedef
typename traits::make_indirect_iterator<iterator_type>::type
indirect_iterator_type;
typedef detail::pass_container<
fail_function, Attribute, indirect_iterator_type, mpl::false_>
pass_container;
iterator_type it = traits::begin(attr);
iterator_type end = traits::end(attr);
pass_container pass(fail_function(sink, ctx, d),
indirect_iterator_type(it), indirect_iterator_type(end));
// generate the minimal required amount of output
typename LoopIter::type i = iter.start();
for (/**/; !pass.is_at_end() && !iter.got_min(i); ++i)
{
if (!generate_subject(pass, attr, Strict()))
{
// if we fail before reaching the minimum iteration
// required, do not output anything and return false
return false;
}
}
if (pass.is_at_end() && !iter.got_min(i))
return false; // insufficient attribute elements
// generate some more up to the maximum specified
for (/**/; !pass.is_at_end() && !iter.got_max(i); ++i)
{
if (!generate_subject(pass, attr, Strict()))
break;
}
return detail::sink_is_good(sink);
}
template <typename Context>
info what(Context& context) const
{
return info("repeat", subject.what(context));
}
Subject subject;
LoopIter iter;
};
template <typename Subject, typename LoopIter>
struct repeat_generator
: base_repeat_generator<
Subject, LoopIter, mpl::false_
, repeat_generator<Subject, LoopIter> >
{
typedef base_repeat_generator<
Subject, LoopIter, mpl::false_, repeat_generator
> base_repeat_generator_;
repeat_generator(Subject const& subject, LoopIter const& iter)
: base_repeat_generator_(subject, iter) {}
};
template <typename Subject, typename LoopIter>
struct strict_repeat_generator
: base_repeat_generator<
Subject, LoopIter, mpl::true_
, strict_repeat_generator<Subject, LoopIter> >
{
typedef base_repeat_generator<
Subject, LoopIter, mpl::true_, strict_repeat_generator
> base_repeat_generator_;
strict_repeat_generator(Subject const& subject, LoopIter const& iter)
: base_repeat_generator_(subject, iter) {}
};
///////////////////////////////////////////////////////////////////////////
// Generator generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Modifiers>
struct make_directive<tag::repeat, Subject, Modifiers>
{
typedef typename mpl::if_<
detail::get_stricttag<Modifiers>
, strict_kleene<Subject>, kleene<Subject>
>::type result_type;
result_type operator()(unused_type, Subject const& subject
, unused_type) const
{
return result_type(subject);
}
};
template <typename T, typename Subject, typename Modifiers>
struct make_directive<
terminal_ex<tag::repeat, fusion::vector1<T> >, Subject, Modifiers>
{
typedef exact_iterator<T> iterator_type;
typedef typename mpl::if_<
detail::get_stricttag<Modifiers>
, strict_repeat_generator<Subject, iterator_type>
, repeat_generator<Subject, iterator_type>
>::type result_type;
template <typename Terminal>
result_type operator()(
Terminal const& term, Subject const& subject, unused_type) const
{
return result_type(subject, fusion::at_c<0>(term.args));
}
};
template <typename T, typename Subject, typename Modifiers>
struct make_directive<
terminal_ex<tag::repeat, fusion::vector2<T, T> >, Subject, Modifiers>
{
typedef finite_iterator<T> iterator_type;
typedef typename mpl::if_<
detail::get_stricttag<Modifiers>
, strict_repeat_generator<Subject, iterator_type>
, repeat_generator<Subject, iterator_type>
>::type result_type;
template <typename Terminal>
result_type operator()(
Terminal const& term, Subject const& subject, unused_type) const
{
return result_type(subject,
iterator_type(
fusion::at_c<0>(term.args)
, fusion::at_c<1>(term.args)
)
);
}
};
template <typename T, typename Subject, typename Modifiers>
struct make_directive<
terminal_ex<tag::repeat
, fusion::vector2<T, inf_type> >, Subject, Modifiers>
{
typedef infinite_iterator<T> iterator_type;
typedef typename mpl::if_<
detail::get_stricttag<Modifiers>
, strict_repeat_generator<Subject, iterator_type>
, repeat_generator<Subject, iterator_type>
>::type result_type;
template <typename Terminal>
result_type operator()(
Terminal const& term, Subject const& subject, unused_type) const
{
return result_type(subject, fusion::at_c<0>(term.args));
}
};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename LoopIter>
struct has_semantic_action<karma::repeat_generator<Subject, LoopIter> >
: unary_has_semantic_action<Subject> {};
template <typename Subject, typename LoopIter>
struct has_semantic_action<karma::strict_repeat_generator<Subject, LoopIter> >
: unary_has_semantic_action<Subject> {};
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename LoopIter, typename Attribute
, typename Context, typename Iterator>
struct handles_container<
karma::repeat_generator<Subject, LoopIter>, Attribute
, Context, Iterator>
: mpl::true_ {};
template <typename Subject, typename LoopIter, typename Attribute
, typename Context, typename Iterator>
struct handles_container<
karma::strict_repeat_generator<Subject, LoopIter>, Attribute
, Context, Iterator>
: mpl::true_ {};
}}}
#endif
@@ -0,0 +1,327 @@
// 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_RIGHT_ALIGNMENT_FEB_27_2007_1216PM)
#define BOOST_SPIRIT_KARMA_RIGHT_ALIGNMENT_FEB_27_2007_1216PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/karma/meta_compiler.hpp>
#include <boost/spirit/home/karma/generator.hpp>
#include <boost/spirit/home/karma/domain.hpp>
#include <boost/spirit/home/karma/detail/output_iterator.hpp>
#include <boost/spirit/home/karma/detail/default_width.hpp>
#include <boost/spirit/home/karma/delimit_out.hpp>
#include <boost/spirit/home/karma/auxiliary/lazy.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/spirit/home/karma/detail/attributes.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/integer_traits.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/detail/workaround.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
// enables right_align[]
template <>
struct use_directive<karma::domain, tag::right_align>
: mpl::true_ {};
// enables right_align(d)[g] and right_align(w)[g], where d is a generator
// and w is a maximum width
template <typename T>
struct use_directive<karma::domain
, terminal_ex<tag::right_align, fusion::vector1<T> > >
: mpl::true_ {};
// enables *lazy* right_align(d)[g], where d provides a generator
template <>
struct use_lazy_directive<karma::domain, tag::right_align, 1>
: mpl::true_ {};
// enables right_align(w, d)[g], where d is a generator and w is a maximum
// width
template <typename Width, typename Padding>
struct use_directive<karma::domain
, terminal_ex<tag::right_align, fusion::vector2<Width, Padding> > >
: spirit::traits::matches<karma::domain, Padding> {};
// enables *lazy* right_align(w, d)[g], where d provides a generator and w
// is a maximum width
template <>
struct use_lazy_directive<karma::domain, tag::right_align, 2>
: mpl::true_ {};
}}
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace karma
{
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::right_align;
#endif
using spirit::right_align_type;
namespace detail
{
///////////////////////////////////////////////////////////////////////
// The right_align_generate template function is used for all the
// different flavors of the right_align[] directive.
///////////////////////////////////////////////////////////////////////
template <typename OutputIterator, typename Context, typename Delimiter,
typename Attribute, typename Embedded, typename Padding>
inline static bool
right_align_generate(OutputIterator& sink, Context& ctx,
Delimiter const& d, Attribute const& attr, Embedded const& e,
unsigned int const width, Padding const& p)
{
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
e; // suppresses warning: C4100: 'e' : unreferenced formal parameter
#endif
// wrap the given output iterator to allow left padding
detail::enable_buffering<OutputIterator> buffering(sink, width);
bool r = false;
// first generate the embedded output
{
detail::disable_counting<OutputIterator> nocounting(sink);
r = e.generate(sink, ctx, d, attr);
} // re-enable counting
buffering.disable(); // do not perform buffering any more
// generate the left padding
detail::enable_counting<OutputIterator> counting(sink, buffering.buffer_size());
while(r && counting.count() < width)
r = p.generate(sink, ctx, unused, unused);
// copy the buffered output to the target output iterator
if (r)
buffering.buffer_copy();
return r;
}
}
///////////////////////////////////////////////////////////////////////////
// The simple left alignment directive is used for right_align[...]
// generators. It uses default values for the generated width (defined via
// the BOOST_KARMA_DEFAULT_FIELD_LENGTH constant) and for the padding
// generator (always spaces).
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Width = detail::default_width>
struct simple_right_alignment
: unary_generator<simple_right_alignment<Subject, Width> >
{
typedef Subject subject_type;
typedef mpl::int_<
generator_properties::countingbuffer | subject_type::properties::value
> properties;
template <typename Context, typename Iterator>
struct attribute
: traits::attribute_of<subject_type, Context, Iterator>
{};
simple_right_alignment(Subject const& subject, Width width = Width())
: subject(subject), width(width) {}
template <typename OutputIterator, typename Context, typename Delimiter
, typename Attribute>
bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
, Attribute const& attr) const
{
return detail::right_align_generate(sink, ctx, d, attr,
subject, width, compile<karma::domain>(' '));
}
template <typename Context>
info what(Context& context) const
{
return info("right_align", subject.what(context));
}
Subject subject;
Width width;
};
///////////////////////////////////////////////////////////////////////////
// The left alignment directive with padding, is used for generators like
// right_align(padding)[...], where padding is a arbitrary generator
// expression. It uses a default value for the generated width (defined
// via the BOOST_KARMA_DEFAULT_FIELD_LENGTH constant).
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Padding
, typename Width = detail::default_width>
struct padding_right_alignment
: unary_generator<padding_right_alignment<Subject, Padding, Width> >
{
typedef Subject subject_type;
typedef Padding padding_type;
typedef mpl::int_<
generator_properties::countingbuffer |
subject_type::properties::value | padding_type::properties::value
> properties;
template <typename Context, typename Iterator>
struct attribute
: traits::attribute_of<subject_type, Context, Iterator>
{};
padding_right_alignment(Subject const& subject, Padding const& padding
, Width width = Width())
: subject(subject), padding(padding), width(width) {}
template <typename OutputIterator, typename Context, typename Delimiter
, typename Attribute>
bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
, Attribute const& attr) const
{
return detail::right_align_generate(sink, ctx, d, attr,
subject, width, padding);
}
template <typename Context>
info what(Context& context) const
{
return info("right_align", subject.what(context));
}
Subject subject;
Padding padding;
Width width;
};
///////////////////////////////////////////////////////////////////////////
// Generator generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
// creates right_align[] directive generator
template <typename Subject, typename Modifiers>
struct make_directive<tag::right_align, Subject, Modifiers>
{
typedef simple_right_alignment<Subject> result_type;
result_type operator()(unused_type, Subject const& subject
, unused_type) const
{
return result_type(subject);
}
};
// creates right_align(width)[] directive generator
template <typename Width, typename Subject, typename Modifiers>
struct make_directive<
terminal_ex<tag::right_align, fusion::vector1<Width> >
, Subject, Modifiers
, typename enable_if_c< integer_traits<Width>::is_integral >::type>
{
typedef simple_right_alignment<Subject, Width> result_type;
template <typename Terminal>
result_type operator()(Terminal const& term, Subject const& subject
, unused_type) const
{
return result_type(subject, fusion::at_c<0>(term.args));
}
};
// creates right_align(pad)[] directive generator
template <typename Padding, typename Subject, typename Modifiers>
struct make_directive<
terminal_ex<tag::right_align, fusion::vector1<Padding> >
, Subject, Modifiers
, typename enable_if<
mpl::and_<
spirit::traits::matches<karma::domain, Padding>,
mpl::not_<mpl::bool_<integer_traits<Padding>::is_integral> >
>
>::type>
{
typedef typename
result_of::compile<karma::domain, Padding, Modifiers>::type
padding_type;
typedef padding_right_alignment<Subject, padding_type> result_type;
template <typename Terminal>
result_type operator()(Terminal const& term, Subject const& subject
, Modifiers const& modifiers) const
{
return result_type(subject
, compile<karma::domain>(fusion::at_c<0>(term.args), modifiers));
}
};
// creates right_align(width, pad)[] directive generator
template <typename Width, typename Padding, typename Subject
, typename Modifiers>
struct make_directive<
terminal_ex<tag::right_align, fusion::vector2<Width, Padding> >
, Subject, Modifiers>
{
typedef typename
result_of::compile<karma::domain, Padding, Modifiers>::type
padding_type;
typedef padding_right_alignment<Subject, padding_type, Width> result_type;
template <typename Terminal>
result_type operator()(Terminal const& term, Subject const& subject
, Modifiers const& modifiers) const
{
return result_type(subject
, compile<karma::domain>(fusion::at_c<1>(term.args), modifiers)
, fusion::at_c<0>(term.args));
}
};
}}} // namespace boost::spirit::karma
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Width>
struct has_semantic_action<karma::simple_right_alignment<Subject, Width> >
: unary_has_semantic_action<Subject> {};
template <typename Subject, typename Padding, typename Width>
struct has_semantic_action<
karma::padding_right_alignment<Subject, Padding, Width> >
: unary_has_semantic_action<Subject> {};
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Width, typename Attribute
, typename Context, typename Iterator>
struct handles_container<
karma::simple_right_alignment<Subject, Width>
, Attribute, Context, Iterator>
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
template <typename Subject, typename Padding, typename Width
, typename Attribute, typename Context, typename Iterator>
struct handles_container<
karma::padding_right_alignment<Subject, Padding, Width>
, Attribute, Context, Iterator>
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
}}}
#endif
@@ -0,0 +1,78 @@
// 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_STRICT_RELAXED_APR_22_2010_0959AM)
#define SPIRIT_STRICT_RELAXED_APR_22_2010_0959AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/modify.hpp>
#include <boost/spirit/home/karma/domain.hpp>
#include <boost/spirit/home/karma/meta_compiler.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_directive<karma::domain, tag::strict> // enables strict[]
: mpl::true_ {};
template <>
struct use_directive<karma::domain, tag::relaxed> // enables relaxed[]
: mpl::true_ {};
///////////////////////////////////////////////////////////////////////////
template <>
struct is_modifier_directive<karma::domain, tag::strict>
: mpl::true_ {};
template <>
struct is_modifier_directive<karma::domain, tag::relaxed>
: mpl::true_ {};
///////////////////////////////////////////////////////////////////////////
// Don't add tag::strict or tag::relaxed if there is already one of those
// in the modifier list
template <typename Current>
struct compound_modifier<Current, tag::strict
, typename enable_if<has_modifier<Current, tag::relaxed> >::type>
: Current
{
compound_modifier()
: Current() {}
compound_modifier(Current const& current, tag::strict const&)
: Current(current) {}
};
template <typename Current>
struct compound_modifier<Current, tag::relaxed
, typename enable_if<has_modifier<Current, tag::strict> >::type>
: Current
{
compound_modifier()
: Current() {}
compound_modifier(Current const& current, tag::relaxed const&)
: Current(current) {}
};
namespace karma
{
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using boost::spirit::strict;
using boost::spirit::relaxed;
#endif
using boost::spirit::strict_type;
using boost::spirit::relaxed_type;
}
}}
#endif
@@ -0,0 +1,85 @@
// 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_UPPER_LOWER_CASE_JANUARY_19_2009_1142AM)
#define SPIRIT_UPPER_LOWER_CASE_JANUARY_19_2009_1142AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/modify.hpp>
#include <boost/spirit/home/karma/domain.hpp>
#include <boost/spirit/home/karma/meta_compiler.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <typename CharEncoding>
struct use_directive<
karma::domain, tag::char_code<tag::upper, CharEncoding> > // enables upper
: mpl::true_ {};
template <typename CharEncoding>
struct use_directive<
karma::domain, tag::char_code<tag::lower, CharEncoding> > // enables lower
: mpl::true_ {};
///////////////////////////////////////////////////////////////////////////
template <typename CharEncoding>
struct is_modifier_directive<karma::domain
, tag::char_code<tag::upper, CharEncoding> >
: mpl::true_ {};
template <typename CharEncoding>
struct is_modifier_directive<karma::domain
, tag::char_code<tag::lower, CharEncoding> >
: mpl::true_ {};
///////////////////////////////////////////////////////////////////////////
// Don't add tag::upper or tag::lower if there is already one of those in
// the modifier list
template <typename Current, typename CharEncoding>
struct compound_modifier<
Current
, tag::char_code<tag::upper, CharEncoding>
, typename enable_if<
has_modifier<Current, tag::char_code<tag::lower, CharEncoding> >
>::type
>
: Current
{
compound_modifier()
: Current() {}
compound_modifier(Current const& current,
tag::char_code<tag::upper, CharEncoding> const&)
: Current(current) {}
};
template <typename Current, typename CharEncoding>
struct compound_modifier<
Current
, tag::char_code<tag::lower, CharEncoding>
, typename enable_if<
has_modifier<Current, tag::char_code<tag::upper, CharEncoding> >
>::type
>
: Current
{
compound_modifier()
: Current() {}
compound_modifier(Current const& current,
tag::char_code<tag::lower, CharEncoding> const&)
: Current(current) {}
};
}}
#endif
@@ -0,0 +1,114 @@
// 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_VERBATIM_MAR_02_2007_0303PM)
#define BOOST_SPIRIT_KARMA_VERBATIM_MAR_02_2007_0303PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/karma/meta_compiler.hpp>
#include <boost/spirit/home/karma/generator.hpp>
#include <boost/spirit/home/karma/domain.hpp>
#include <boost/spirit/home/karma/detail/unused_delimiter.hpp>
#include <boost/spirit/home/karma/delimit_out.hpp>
#include <boost/spirit/home/karma/auxiliary/lazy.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/spirit/home/karma/detail/attributes.hpp>
#include <boost/spirit/home/support/info.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_directive<karma::domain, tag::verbatim> // enables verbatim[]
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace karma
{
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::verbatim;
#endif
using spirit::verbatim_type;
///////////////////////////////////////////////////////////////////////////
// The verbatim generator is used for verbatim[...] directives.
///////////////////////////////////////////////////////////////////////////
template <typename Subject>
struct verbatim_generator : unary_generator<verbatim_generator<Subject> >
{
typedef Subject subject_type;
typedef typename subject_type::properties properties;
template <typename Context, typename Iterator>
struct attribute
: traits::attribute_of<subject_type, Context, Iterator>
{};
verbatim_generator(Subject const& subject)
: subject(subject) {}
template <typename OutputIterator, typename Context, typename Delimiter
, typename Attribute>
bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
, Attribute const& attr) const
{
// the verbatim generator simply dispatches to the embedded
// generator while supplying unused_delimiter as the new delimiter
// to avoid delimiting down the generator stream
typedef detail::unused_delimiter<Delimiter> unused_delimiter;
return subject.generate(sink, ctx, unused_delimiter(d), attr) &&
karma::delimit_out(sink, d); // always do post-delimiting
}
template <typename Context>
info what(Context& context) const
{
return info("verbatim", subject.what(context));
}
Subject subject;
};
///////////////////////////////////////////////////////////////////////////
// Generator generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Modifiers>
struct make_directive<tag::verbatim, Subject, Modifiers>
{
typedef verbatim_generator<Subject> result_type;
result_type operator()(unused_type, Subject const& subject, unused_type) const
{
return result_type(subject);
}
};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Subject>
struct has_semantic_action<karma::verbatim_generator<Subject> >
: unary_has_semantic_action<Subject> {};
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Attribute, typename Context
, typename Iterator>
struct handles_container<karma::verbatim_generator<Subject>, Attribute
, Context, Iterator>
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
}}}
#endif