stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork
This commit is contained in:
@@ -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
|
||||
+335
@@ -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
|
||||
+318
@@ -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
|
||||
+327
@@ -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
|
||||
|
||||
+78
@@ -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
|
||||
+85
@@ -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
|
||||
Reference in New Issue
Block a user