Mercurial > hg > vamp-build-and-test
diff DEPENDENCIES/generic/include/boost/spirit/home/karma/directive/columns.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DEPENDENCIES/generic/include/boost/spirit/home/karma/directive/columns.hpp Tue Aug 05 11:11:38 2014 +0100 @@ -0,0 +1,292 @@ +// 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> + +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