summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/spirit/repository
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 18:24:20 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 18:24:20 +0000
commit483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch)
treee5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/boost/libs/spirit/repository
parentInitial commit. (diff)
downloadceph-483eb2f56657e8e7f419ab1a4fab8dce9ade8609.tar.xz
ceph-483eb2f56657e8e7f419ab1a4fab8dce9ade8609.zip
Adding upstream version 14.2.21.upstream/14.2.21upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/spirit/repository')
-rw-r--r--src/boost/libs/spirit/repository/example/karma/Jamfile16
-rw-r--r--src/boost/libs/spirit/repository/example/karma/calc2_ast.hpp179
-rw-r--r--src/boost/libs/spirit/repository/example/karma/calc2_ast_dump_sr.cpp181
-rw-r--r--src/boost/libs/spirit/repository/example/karma/confix.cpp63
-rw-r--r--src/boost/libs/spirit/repository/example/karma/mini_xml_karma_sr.cpp235
-rw-r--r--src/boost/libs/spirit/repository/example/qi/Jamfile23
-rw-r--r--src/boost/libs/spirit/repository/example/qi/advance.cpp110
-rw-r--r--src/boost/libs/spirit/repository/example/qi/calc1_sr.cpp118
-rw-r--r--src/boost/libs/spirit/repository/example/qi/confix.cpp113
-rw-r--r--src/boost/libs/spirit/repository/example/qi/derived.cpp158
-rw-r--r--src/boost/libs/spirit/repository/example/qi/distinct.cpp60
-rw-r--r--src/boost/libs/spirit/repository/example/qi/flush_multi_pass.cpp98
-rw-r--r--src/boost/libs/spirit/repository/example/qi/flush_multi_pass.txt8
-rw-r--r--src/boost/libs/spirit/repository/example/qi/iter_pos_parser.cpp51
-rw-r--r--src/boost/libs/spirit/repository/example/qi/keywords.cpp214
-rw-r--r--src/boost/libs/spirit/repository/example/qi/mini_xml2_sr.cpp246
-rw-r--r--src/boost/libs/spirit/repository/example/qi/options.cpp122
-rw-r--r--src/boost/libs/spirit/repository/example/qi/seek.cpp48
-rw-r--r--src/boost/libs/spirit/repository/index.html15
-rw-r--r--src/boost/libs/spirit/repository/meta/libraries.json18
-rw-r--r--src/boost/libs/spirit/repository/test/Jamfile56
-rw-r--r--src/boost/libs/spirit/repository/test/karma/confix.cpp123
-rw-r--r--src/boost/libs/spirit/repository/test/karma/subrule.cpp186
-rw-r--r--src/boost/libs/spirit/repository/test/karma/test.hpp297
-rw-r--r--src/boost/libs/spirit/repository/test/qi/advance.cpp111
-rw-r--r--src/boost/libs/spirit/repository/test/qi/confix.cpp147
-rw-r--r--src/boost/libs/spirit/repository/test/qi/distinct.cpp101
-rw-r--r--src/boost/libs/spirit/repository/test/qi/keywords.cpp269
-rw-r--r--src/boost/libs/spirit/repository/test/qi/seek.cpp101
-rw-r--r--src/boost/libs/spirit/repository/test/qi/subrule.cpp397
-rw-r--r--src/boost/libs/spirit/repository/test/qi/test.hpp102
-rw-r--r--src/boost/libs/spirit/repository/test/test_headers/Jamfile81
-rw-r--r--src/boost/libs/spirit/repository/test/test_headers/main.cpp14
-rw-r--r--src/boost/libs/spirit/repository/test/test_headers/test.cpp22
34 files changed, 4083 insertions, 0 deletions
diff --git a/src/boost/libs/spirit/repository/example/karma/Jamfile b/src/boost/libs/spirit/repository/example/karma/Jamfile
new file mode 100644
index 00000000..b52e3b80
--- /dev/null
+++ b/src/boost/libs/spirit/repository/example/karma/Jamfile
@@ -0,0 +1,16 @@
+#==============================================================================
+# Copyright (c) 2009 Chris Hoeppler
+#
+# 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)
+#==============================================================================
+
+project spirit_v2_repository/example_karma
+ : requirements
+ <c++-template-depth>300
+ ;
+
+exe karma_confix : confix.cpp ;
+exe calc2_ast_dump_sr : calc2_ast_dump_sr.cpp ;
+exe mini_xml_karma_sr : mini_xml_karma_sr.cpp ;
+
diff --git a/src/boost/libs/spirit/repository/example/karma/calc2_ast.hpp b/src/boost/libs/spirit/repository/example/karma/calc2_ast.hpp
new file mode 100644
index 00000000..53fadf76
--- /dev/null
+++ b/src/boost/libs/spirit/repository/example/karma/calc2_ast.hpp
@@ -0,0 +1,179 @@
+/*=============================================================================
+ Copyright (c) 2001-2010 Joel de Guzman
+ Copyright (c) 2001-2012 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// A Calculator example demonstrating generation of AST which gets dumped into
+// a human readable format afterwards.
+//
+// [ JDG April 28, 2008 ]
+// [ HK April 28, 2008 ]
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#if !defined(SPIRIT_EXAMPLE_CALC2_AST_APR_30_2008_1011AM)
+#define SPIRIT_EXAMPLE_CALC2_AST_APR_30_2008_1011AM
+
+#include <boost/variant.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+#include <boost/spirit/include/phoenix_function.hpp>
+#include <boost/spirit/include/phoenix_statement.hpp>
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/include/support_attributes_fwd.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+// Our AST
+///////////////////////////////////////////////////////////////////////////////
+struct binary_op;
+struct unary_op;
+struct nil {};
+
+struct expression_ast
+{
+ typedef
+ boost::variant<
+ nil // can't happen!
+ , int
+ , boost::recursive_wrapper<binary_op>
+ , boost::recursive_wrapper<unary_op>
+ >
+ type;
+
+ // expose variant types
+ typedef type::types types;
+
+ // expose variant functionality
+ int which() const { return expr.which(); }
+
+ // constructors
+ expression_ast()
+ : expr(nil()) {}
+
+ expression_ast(unary_op const& expr)
+ : expr(expr) {}
+
+ expression_ast(binary_op const& expr)
+ : expr(expr) {}
+
+ expression_ast(unsigned int expr)
+ : expr(expr) {}
+
+ expression_ast(type const& expr)
+ : expr(expr) {}
+
+ expression_ast& operator+=(expression_ast const& rhs);
+ expression_ast& operator-=(expression_ast const& rhs);
+ expression_ast& operator*=(expression_ast const& rhs);
+ expression_ast& operator/=(expression_ast const& rhs);
+
+ type expr;
+};
+
+// expose variant functionality
+namespace boost
+{
+ // this function has to live in namespace boost for ADL to correctly find it
+ template <typename T>
+ inline T get(expression_ast const& expr)
+ {
+ return boost::get<T>(expr.expr);
+ }
+
+ // the specialization below tells Spirit to handle expression_ast as if it
+ // where a 'real' variant
+ namespace spirit { namespace traits
+ {
+ // the specialization below tells Spirit to handle expression_ast as
+ // if it where a 'real' variant (if used with Spirit.Karma)
+ template <>
+ struct not_is_variant<expression_ast, karma::domain>
+ : mpl::false_ {};
+
+ // the specialization of variant_which allows to generically extract
+ // the current type stored in the given variant like type
+ template <>
+ struct variant_which<expression_ast>
+ {
+ static int call(expression_ast const& v)
+ {
+ return v.which();
+ }
+ };
+ }}
+}
+
+///////////////////////////////////////////////////////////////////////////////
+struct binary_op
+{
+ binary_op() {}
+
+ binary_op(
+ char op
+ , expression_ast const& left
+ , expression_ast const& right)
+ : op(op), left(left), right(right) {}
+
+ char op;
+ expression_ast left;
+ expression_ast right;
+};
+
+struct unary_op
+{
+ unary_op(
+ char op
+ , expression_ast const& right)
+ : op(op), right(right) {}
+
+ char op;
+ expression_ast right;
+};
+
+inline expression_ast& expression_ast::operator+=(expression_ast const& rhs)
+{
+ expr = binary_op('+', expr, rhs);
+ return *this;
+}
+
+inline expression_ast& expression_ast::operator-=(expression_ast const& rhs)
+{
+ expr = binary_op('-', expr, rhs);
+ return *this;
+}
+
+inline expression_ast& expression_ast::operator*=(expression_ast const& rhs)
+{
+ expr = binary_op('*', expr, rhs);
+ return *this;
+}
+
+inline expression_ast& expression_ast::operator/=(expression_ast const& rhs)
+{
+ expr = binary_op('/', expr, rhs);
+ return *this;
+}
+
+// We should be using expression_ast::operator-. There's a bug
+// in phoenix type deduction mechanism that prevents us from
+// doing so. Phoenix will be switching to BOOST_TYPEOF. In the
+// meantime, we will use a phoenix::function below:
+template <char Op>
+struct unary_expr
+{
+ template <typename T>
+ struct result { typedef T type; };
+
+ expression_ast operator()(expression_ast const& expr) const
+ {
+ return unary_op(Op, expr);
+ }
+};
+
+boost::phoenix::function<unary_expr<'+'> > pos;
+boost::phoenix::function<unary_expr<'-'> > neg;
+
+#endif
diff --git a/src/boost/libs/spirit/repository/example/karma/calc2_ast_dump_sr.cpp b/src/boost/libs/spirit/repository/example/karma/calc2_ast_dump_sr.cpp
new file mode 100644
index 00000000..12f18931
--- /dev/null
+++ b/src/boost/libs/spirit/repository/example/karma/calc2_ast_dump_sr.cpp
@@ -0,0 +1,181 @@
+/*=============================================================================
+ Copyright (c) 2001-2010 Joel de Guzman
+ Copyright (c) 2001-2010 Hartmut Kaiser
+ Copyright (c) 2009 Francois Barel
+
+ 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// A Calculator example demonstrating generation of AST which gets dumped into
+// a human readable format afterwards.
+//
+// [ JDG April 28, 2008 ]
+// [ HK April 28, 2008 ]
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/config/warning_disable.hpp>
+
+#include <iostream>
+#include <vector>
+#include <string>
+
+#include "calc2_ast.hpp"
+
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/include/karma.hpp>
+#include <boost/spirit/repository/include/karma_subrule.hpp>
+#include <boost/fusion/include/adapt_struct.hpp>
+
+using namespace boost::spirit;
+using namespace boost::spirit::ascii;
+namespace repo = boost::spirit::repository;
+
+///////////////////////////////////////////////////////////////////////////////
+// Our calculator parser grammar
+///////////////////////////////////////////////////////////////////////////////
+template <typename Iterator>
+struct calculator
+ : qi::grammar<Iterator, expression_ast(), space_type>
+{
+ calculator() : calculator::base_type(expression)
+ {
+ expression =
+ term [_val = _1]
+ >> *( ('+' >> term [_val += _1])
+ | ('-' >> term [_val -= _1])
+ )
+ ;
+
+ term =
+ factor [_val = _1]
+ >> *( ('*' >> factor [_val *= _1])
+ | ('/' >> factor [_val /= _1])
+ )
+ ;
+
+ factor =
+ uint_ [_val = _1]
+ | '(' >> expression [_val = _1] >> ')'
+ | ('-' >> factor [_val = neg(_1)])
+ | ('+' >> factor [_val = pos(_1)])
+ ;
+ }
+
+ qi::rule<Iterator, expression_ast(), space_type> expression, term, factor;
+};
+
+// We need to tell fusion about our binary_op and unary_op structs
+// to make them a first-class fusion citizen
+//
+// Note: we register the members exactly in the same sequence as we need them
+// in the grammar
+BOOST_FUSION_ADAPT_STRUCT(
+ binary_op,
+ (expression_ast, left)
+ (char, op)
+ (expression_ast, right)
+)
+
+BOOST_FUSION_ADAPT_STRUCT(
+ unary_op,
+ (char, op)
+ (expression_ast, right)
+)
+
+///////////////////////////////////////////////////////////////////////////////
+// Our AST grammar for the generator, this just dumps the AST as a expression
+///////////////////////////////////////////////////////////////////////////////
+template <typename OuputIterator>
+struct dump_ast
+ : karma::grammar<OuputIterator, expression_ast(), space_type>
+{
+ dump_ast() : dump_ast::base_type(entry)
+ {
+ //[calc2_ast_dump_sr_def
+ entry %= (
+ ast_node %= int_ | binary_node | unary_node
+
+ , binary_node %= '(' << ast_node << char_ << ast_node << ')'
+
+ , unary_node %= '(' << char_ << ast_node << ')'
+ );
+ //]
+ }
+
+ karma::rule<OuputIterator, expression_ast(), space_type> entry;
+
+ repo::karma::subrule<0, expression_ast()> ast_node;
+ repo::karma::subrule<1, binary_op()> binary_node;
+ repo::karma::subrule<2, unary_op()> unary_node;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Main program
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ std::cout << "/////////////////////////////////////////////////////////\n\n";
+ std::cout << "Dump AST's for simple expressions...\n\n";
+ std::cout << "/////////////////////////////////////////////////////////\n\n";
+ std::cout << "Type an expression...or [q or Q] to quit\n\n";
+
+ // Our parser grammar definitions
+ typedef std::string::const_iterator iterator_type;
+ typedef calculator<iterator_type> calculator;
+
+ calculator calc;
+
+ // Our generator grammar definitions
+ typedef std::back_insert_iterator<std::string> output_iterator_type;
+ typedef dump_ast<output_iterator_type> dump_ast;
+
+ dump_ast ast_grammar;
+
+ std::string str;
+ while (std::getline(std::cin, str))
+ {
+ if (str.empty() || str[0] == 'q' || str[0] == 'Q')
+ break;
+
+ expression_ast ast;
+ std::string::const_iterator iter = str.begin();
+ std::string::const_iterator end = str.end();
+ bool r = qi::phrase_parse(iter, end, calc, space, ast);
+
+ if (r && iter == end)
+ {
+ std::string generated;
+ output_iterator_type outit(generated);
+ r = karma::generate_delimited(outit, ast_grammar, space, ast);
+
+ if (r)
+ {
+ std::cout << "Got AST:" << std::endl << generated
+ << std::endl;
+ std::cout << "-------------------------\n";
+ }
+ else
+ {
+ std::cout << "-------------------------\n";
+ std::cout << "Generating failed\n";
+ std::cout << "-------------------------\n";
+ }
+ }
+ else
+ {
+ std::string rest(iter, end);
+ std::cout << "-------------------------\n";
+ std::cout << "Parsing failed\n";
+ std::cout << "stopped at: \": " << rest << "\"\n";
+ std::cout << "-------------------------\n";
+ }
+ }
+
+ std::cout << "Bye... :-) \n\n";
+ return 0;
+}
+
+
diff --git a/src/boost/libs/spirit/repository/example/karma/confix.cpp b/src/boost/libs/spirit/repository/example/karma/confix.cpp
new file mode 100644
index 00000000..4ea6f21c
--- /dev/null
+++ b/src/boost/libs/spirit/repository/example/karma/confix.cpp
@@ -0,0 +1,63 @@
+// Copyright (c) 2001-2010 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)
+
+// The purpose of this example is to demonstrate different use cases for the
+// confix generator.
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+//[karma_confix_includes
+#include <boost/spirit/include/karma.hpp>
+#include <boost/spirit/repository/include/karma_confix.hpp>
+//]
+
+//[karma_confix_namespace
+using namespace boost::spirit;
+using namespace boost::spirit::ascii;
+using boost::spirit::repository::confix;
+//]
+
+int main()
+{
+//[karma_confix_cpp_comment
+ // C++ comment
+ std::cout <<
+ karma::format_delimited(
+ confix("//", eol)[string], // format description
+ space, // delimiter
+ "This is a comment" // data
+ ) << std::endl;
+//]
+
+//[karma_confix_c_comment
+ // C comment
+ std::cout <<
+ karma::format_delimited(
+ confix("/*", "*/")[string], // format description
+ space, // delimiter
+ "This is a comment" // data
+ ) << std::endl;
+//]
+
+//[karma_confix_function
+ // Generate a function call with an arbitrary parameter list
+ std::vector<std::string> parameters;
+ parameters.push_back("par1");
+ parameters.push_back("par2");
+ parameters.push_back("par3");
+
+ std::cout <<
+ karma::format(
+ string << confix('(', ')')[string % ','], // format description
+ "func", // function name
+ parameters // parameter names
+ ) << std::endl;
+//]
+
+ return 0;
+}
+
diff --git a/src/boost/libs/spirit/repository/example/karma/mini_xml_karma_sr.cpp b/src/boost/libs/spirit/repository/example/karma/mini_xml_karma_sr.cpp
new file mode 100644
index 00000000..677cb263
--- /dev/null
+++ b/src/boost/libs/spirit/repository/example/karma/mini_xml_karma_sr.cpp
@@ -0,0 +1,235 @@
+/*=============================================================================
+ Copyright (c) 2001-2010 Joel de Guzman
+ Copyright (c) 2001-2010 Hartmut Kaiser
+ Copyright (c) 2009 Francois Barel
+
+ 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// A mini XML-like parser, Karma is used to print out the generated AST
+//
+// [ JDG March 25, 2007 ] spirit2
+// [ HK April 02, 2007 ] spirit2
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include <boost/config/warning_disable.hpp>
+
+#include <boost/spirit/include/qi.hpp>
+//[mini_xml_karma_sr_includes
+#include <boost/spirit/include/karma.hpp>
+#include <boost/spirit/repository/include/karma_subrule.hpp>
+#include <boost/spirit/include/phoenix_core.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+#include <boost/spirit/include/phoenix_fusion.hpp>
+//]
+#include <boost/spirit/include/phoenix_function.hpp>
+#include <boost/spirit/include/phoenix_stl.hpp>
+#include <boost/fusion/include/adapt_struct.hpp>
+#include <boost/variant/recursive_variant.hpp>
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <vector>
+
+//[mini_xml_karma_sr_using
+using namespace boost::spirit;
+using namespace boost::spirit::ascii;
+namespace repo = boost::spirit::repository;
+//]
+
+namespace fusion = boost::fusion;
+namespace phoenix = boost::phoenix;
+
+using phoenix::at_c;
+using phoenix::push_back;
+
+///////////////////////////////////////////////////////////////////////////////
+// Our mini XML tree representation
+///////////////////////////////////////////////////////////////////////////////
+struct mini_xml;
+
+typedef
+ boost::variant<
+ boost::recursive_wrapper<mini_xml>
+ , std::string
+ >
+mini_xml_node;
+
+struct mini_xml
+{
+ std::string name; // tag name
+ std::vector<mini_xml_node> children; // children
+};
+
+// We need to tell fusion about our mini_xml struct
+// to make it a first-class fusion citizen
+BOOST_FUSION_ADAPT_STRUCT(
+ mini_xml,
+ (std::string, name)
+ (std::vector<mini_xml_node>, children)
+)
+
+///////////////////////////////////////////////////////////////////////////////
+// Our mini XML grammar definition
+///////////////////////////////////////////////////////////////////////////////
+template <typename Iterator>
+struct mini_xml_parser :
+ qi::grammar<Iterator, mini_xml(), space_type>
+{
+ mini_xml_parser() : mini_xml_parser::base_type(xml)
+ {
+ text = lexeme[+(char_ - '<') [_val += _1]];
+ node = (xml | text) [_val = _1];
+
+ start_tag =
+ '<'
+ >> !lit('/')
+ >> lexeme[+(char_ - '>') [_val += _1]]
+ >> '>'
+ ;
+
+ end_tag =
+ "</"
+ >> lit(_r1)
+ >> '>'
+ ;
+
+ xml =
+ start_tag [at_c<0>(_val) = _1]
+ >> *node [push_back(at_c<1>(_val), _1)]
+ >> end_tag(at_c<0>(_val))
+ ;
+ }
+
+ qi::rule<Iterator, mini_xml(), space_type> xml;
+ qi::rule<Iterator, mini_xml_node(), space_type> node;
+ qi::rule<Iterator, std::string(), space_type> text;
+ qi::rule<Iterator, std::string(), space_type> start_tag;
+ qi::rule<Iterator, void(std::string), space_type> end_tag;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// A couple of phoenix functions helping to access the elements of the
+// generated AST
+///////////////////////////////////////////////////////////////////////////////
+template <typename T>
+struct get_element
+{
+ template <typename T1>
+ struct result { typedef T const& type; };
+
+ T const& operator()(mini_xml_node const& node) const
+ {
+ return boost::get<T>(node);
+ }
+};
+
+phoenix::function<get_element<std::string> > _string;
+phoenix::function<get_element<mini_xml> > _xml;
+
+///////////////////////////////////////////////////////////////////////////////
+// The output grammar defining the format of the generated data
+///////////////////////////////////////////////////////////////////////////////
+//[mini_xml_karma_sr_grammar
+template <typename OutputIterator>
+struct mini_xml_generator
+ : karma::grammar<OutputIterator, mini_xml()>
+{
+ mini_xml_generator() : mini_xml_generator::base_type(entry)
+ {
+ entry %= (
+ xml =
+ '<' << string[_1 = at_c<0>(_val)] << '>'
+ << (*node)[_1 = at_c<1>(_val)]
+ << "</" << string[_1 = at_c<0>(_val)] << '>'
+
+ , node %= string | xml
+ );
+ }
+
+ karma::rule<OutputIterator, mini_xml()> entry;
+
+ repo::karma::subrule<0, mini_xml()> xml;
+ repo::karma::subrule<1, mini_xml_node()> node;
+};
+//]
+
+///////////////////////////////////////////////////////////////////////////////
+// Main program
+///////////////////////////////////////////////////////////////////////////////
+int main(int argc, char **argv)
+{
+ char const* filename;
+ if (argc > 1)
+ {
+ filename = argv[1];
+ }
+ else
+ {
+ std::cerr << "Error: No input file provided." << std::endl;
+ return 1;
+ }
+
+ std::ifstream in(filename, std::ios_base::in);
+
+ if (!in)
+ {
+ std::cerr << "Error: Could not open input file: "
+ << filename << std::endl;
+ return 1;
+ }
+
+ std::string storage; // We will read the contents here.
+ in.unsetf(std::ios::skipws); // No white space skipping!
+ std::copy(
+ std::istream_iterator<char>(in),
+ std::istream_iterator<char>(),
+ std::back_inserter(storage));
+
+ typedef mini_xml_parser<std::string::const_iterator> mini_xml_parser;
+ mini_xml_parser xmlin; // Our grammar definition
+ mini_xml ast; // our tree
+
+ std::string::const_iterator iter = storage.begin();
+ std::string::const_iterator end = storage.end();
+ bool r = qi::phrase_parse(iter, end, xmlin, space, ast);
+
+ if (r && iter == end)
+ {
+ std::cout << "-------------------------\n";
+ std::cout << "Parsing succeeded\n";
+ std::cout << "-------------------------\n";
+
+ typedef std::back_insert_iterator<std::string> outiter_type;
+ typedef mini_xml_generator<outiter_type> mini_xml_generator;
+
+ mini_xml_generator xmlout; // Our grammar definition
+
+ std::string generated;
+ outiter_type outit(generated);
+ bool r = karma::generate(outit, xmlout, ast);
+
+ if (r)
+ std::cout << generated << std::endl;
+ return 0;
+ }
+ else
+ {
+ std::string::const_iterator begin = storage.begin();
+ std::size_t dist = std::distance(begin, iter);
+ std::string::const_iterator some =
+ iter + (std::min)(storage.size()-dist, std::size_t(30));
+ std::string context(iter, some);
+ std::cout << "-------------------------\n";
+ std::cout << "Parsing failed\n";
+ std::cout << "stopped at: \": " << context << "...\"\n";
+ std::cout << "-------------------------\n";
+ return 1;
+ }
+}
+
+
diff --git a/src/boost/libs/spirit/repository/example/qi/Jamfile b/src/boost/libs/spirit/repository/example/qi/Jamfile
new file mode 100644
index 00000000..1857b318
--- /dev/null
+++ b/src/boost/libs/spirit/repository/example/qi/Jamfile
@@ -0,0 +1,23 @@
+#==============================================================================
+# Copyright (c) 2001-2009 Joel de Guzman
+# Copyright (c) 2001-2009 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)
+#==============================================================================
+
+project spirit_v2_repository/example_qi
+ : requirements
+ <c++-template-depth>300
+ ;
+
+exe qi_confix : confix.cpp ;
+exe qi_distinct : distinct.cpp ;
+exe flush_multi_pass : flush_multi_pass.cpp ;
+exe calc1_sr : calc1_sr.cpp ;
+exe mini_xml2_sr : mini_xml2_sr.cpp ;
+exe advance : advance.cpp ;
+exe keywords : keywords.cpp ;
+exe derived : derived.cpp ;
+exe options : options.cpp ;
+exe seek : seek.cpp ;
diff --git a/src/boost/libs/spirit/repository/example/qi/advance.cpp b/src/boost/libs/spirit/repository/example/qi/advance.cpp
new file mode 100644
index 00000000..e47d32ee
--- /dev/null
+++ b/src/boost/libs/spirit/repository/example/qi/advance.cpp
@@ -0,0 +1,110 @@
+// Copyright (c) 2011 Aaron Graham
+//
+// 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)
+
+// The purpose of this example is to demonstrate the use of the advance parser.
+
+//[qi_advance_includes
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+#include <boost/spirit/repository/include/qi_advance.hpp>
+//]
+
+#include <list>
+#include <string>
+
+//[qi_advance_namespaces
+namespace qi = boost::spirit::qi;
+using boost::spirit::repository::qi::advance;
+//]
+
+namespace client
+{
+ //[qi_advance_grammar
+ template <typename Iterator>
+ struct advance_grammar : qi::grammar<Iterator, qi::locals<int> >
+ {
+ advance_grammar() : advance_grammar::base_type(start)
+ {
+ using qi::byte_;
+ using qi::eoi;
+ using namespace qi::labels;
+
+ start
+ = byte_ [_a = _1]
+ >> advance(_a)
+ >> "boost"
+ >> byte_ [_a = _1]
+ >> (advance(_a) | "qi") // note alternative when advance fails
+ >> eoi
+ ;
+ }
+
+ qi::rule<Iterator, qi::locals<int> > start;
+ };
+ //]
+}
+
+int main()
+{
+ // This parser is tested with both random access iterators (std::string)
+ // and bidirectional iterators (std::list).
+ char const* result;
+
+ //[qi_advance_example1
+ unsigned char const alt1[] =
+ {
+ 5, // number of bytes to advance
+ 1, 2, 3, 4, 5, // data to advance through
+ 'b', 'o', 'o', 's', 't', // word to parse
+ 2, // number of bytes to advance
+ 11, 12 // more data to advance through
+ // eoi
+ };
+
+ std::string const alt1_string(alt1, alt1 + sizeof alt1);
+ std::list<unsigned char> const alt1_list(alt1, alt1 + sizeof alt1);
+
+ result =
+ qi::parse(alt1_string.begin(), alt1_string.end()
+ , client::advance_grammar<std::string::const_iterator>())
+ ? "succeeded" : "failed";
+ std::cout << "Parsing alt1 using random access iterator " << result << std::endl;
+
+ result =
+ qi::parse(alt1_list.begin(), alt1_list.end()
+ , client::advance_grammar<std::list<unsigned char>::const_iterator>())
+ ? "succeeded" : "failed";
+ std::cout << "Parsing alt1 using bidirectional iterator " << result << std::endl;
+ //]
+
+ //[qi_advance_example2
+ unsigned char const alt2[] =
+ {
+ 2, // number of bytes to advance
+ 1, 2, // data to advance through
+ 'b', 'o', 'o', 's', 't', // word to parse
+ 4, // number of bytes to advance
+ 'q', 'i' // alternative (advance won't work)
+ // eoi
+ };
+
+ std::string const alt2_string(alt2, alt2 + sizeof alt2);
+ std::list<unsigned char> const alt2_list(alt2, alt2 + sizeof alt2);
+
+ result =
+ qi::parse(alt2_string.begin(), alt2_string.end()
+ , client::advance_grammar<std::string::const_iterator>())
+ ? "succeeded" : "failed";
+ std::cout << "Parsing alt2 using random access iterator " << result << std::endl;
+
+ result =
+ qi::parse(alt2_list.begin(), alt2_list.end()
+ , client::advance_grammar<std::list<unsigned char>::const_iterator>())
+ ? "succeeded" : "failed";
+ std::cout << "Parsing alt2 using bidirectional iterator " << result << std::endl;
+ //]
+
+ return 0;
+}
diff --git a/src/boost/libs/spirit/repository/example/qi/calc1_sr.cpp b/src/boost/libs/spirit/repository/example/qi/calc1_sr.cpp
new file mode 100644
index 00000000..031a33f5
--- /dev/null
+++ b/src/boost/libs/spirit/repository/example/qi/calc1_sr.cpp
@@ -0,0 +1,118 @@
+/*=============================================================================
+ Copyright (c) 2001-2010 Joel de Guzman
+ Copyright (c) 2009 Francois Barel
+
+ 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// Plain calculator example demonstrating the grammar. The parser is a
+// syntax checker only and does not do any semantic evaluation.
+//
+// [ JDG May 10, 2002 ] spirit1
+// [ JDG March 4, 2007 ] spirit2
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include <boost/config/warning_disable.hpp>
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/repository/include/qi_subrule.hpp>
+#include <iostream>
+#include <string>
+
+namespace client
+{
+ namespace qi = boost::spirit::qi;
+ namespace repo = boost::spirit::repository;
+ namespace ascii = boost::spirit::ascii;
+
+ ///////////////////////////////////////////////////////////////////////////////
+ // Our calculator grammar
+ ///////////////////////////////////////////////////////////////////////////////
+ template <typename Iterator>
+ struct calculator : qi::grammar<Iterator, ascii::space_type>
+ {
+ calculator() : calculator::base_type(entry)
+ {
+ using qi::uint_;
+
+ //[calc1_sr_def
+ entry = (
+ expression =
+ term
+ >> *( ('+' >> term)
+ | ('-' >> term)
+ )
+
+ , term =
+ factor
+ >> *( ('*' >> factor)
+ | ('/' >> factor)
+ )
+
+ , factor =
+ uint_
+ | '(' >> expression >> ')'
+ | ('-' >> factor)
+ | ('+' >> factor)
+ );
+ //]
+ }
+
+ qi::rule<Iterator, ascii::space_type> entry;
+
+ repo::qi::subrule<0> expression;
+ repo::qi::subrule<1> term;
+ repo::qi::subrule<2> factor;
+ };
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Main program
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ std::cout << "/////////////////////////////////////////////////////////\n\n";
+ std::cout << "Expression parser...\n\n";
+ std::cout << "/////////////////////////////////////////////////////////\n\n";
+ std::cout << "Type an expression...or [q or Q] to quit\n\n";
+
+ using boost::spirit::ascii::space;
+ typedef std::string::const_iterator iterator_type;
+ typedef client::calculator<iterator_type> calculator;
+
+ calculator calc; // Our grammar
+
+ std::string str;
+ while (std::getline(std::cin, str))
+ {
+ if (str.empty() || str[0] == 'q' || str[0] == 'Q')
+ break;
+
+ std::string::const_iterator iter = str.begin();
+ std::string::const_iterator end = str.end();
+ bool r = phrase_parse(iter, end, calc, space);
+
+ if (r && iter == end)
+ {
+ std::cout << "-------------------------\n";
+ std::cout << "Parsing succeeded\n";
+ std::cout << "-------------------------\n";
+ }
+ else
+ {
+ std::string rest(iter, end);
+ std::cout << "-------------------------\n";
+ std::cout << "Parsing failed\n";
+ std::cout << "stopped at: \": " << rest << "\"\n";
+ std::cout << "-------------------------\n";
+ }
+ }
+
+ std::cout << "Bye... :-) \n\n";
+ return 0;
+}
+
+
diff --git a/src/boost/libs/spirit/repository/example/qi/confix.cpp b/src/boost/libs/spirit/repository/example/qi/confix.cpp
new file mode 100644
index 00000000..2426e824
--- /dev/null
+++ b/src/boost/libs/spirit/repository/example/qi/confix.cpp
@@ -0,0 +1,113 @@
+// Copyright (c) 2009 Chris Hoeppler
+//
+// 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)
+
+// The purpose of this example is to demonstrate different use cases for the
+// confix directive.
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+//[qi_confix_includes
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/repository/include/qi_confix.hpp>
+//]
+
+namespace client {
+//[qi_confix_using
+ using boost::spirit::eol;
+ using boost::spirit::lexeme;
+ using boost::spirit::ascii::alnum;
+ using boost::spirit::ascii::char_;
+ using boost::spirit::ascii::space;
+ using boost::spirit::qi::parse;
+ using boost::spirit::qi::phrase_parse;
+ using boost::spirit::repository::confix;
+//]
+
+//[qi_confix_cpp_comment
+ template <typename Iterator>
+ bool parse_cpp_comment(Iterator first, Iterator last, std::string& attr)
+ {
+ bool r = parse(first, last,
+ confix("//", eol)[*(char_ - eol)], // grammar
+ attr); // attribute
+
+ if (!r || first != last) // fail if we did not get a full match
+ return false;
+ return r;
+ }
+//]
+
+//[qi_confix_c_comment
+ template <typename Iterator>
+ bool parse_c_comment(Iterator first, Iterator last, std::string& attr)
+ {
+ bool r = parse(first, last,
+ confix("/*", "*/")[*(char_ - "*/")], // grammar
+ attr); // attribute
+
+ if (!r || first != last) // fail if we did not get a full match
+ return false;
+ return r;
+ }
+//]
+
+//[qi_confix_tagged_data
+ template <typename Iterator>
+ bool parse_tagged(Iterator first, Iterator last, std::string& attr)
+ {
+ bool r = phrase_parse(first, last,
+ confix("<b>", "</b>")[lexeme[*(char_ - '<')]], // grammar
+ space, // skip
+ attr); // attribute
+
+ if (!r || first != last) // fail if we did not get a full match
+ return false;
+ return r;
+ }
+//]
+}
+
+
+int main()
+{
+ // C++ comment
+ std::string comment("// This is a comment\n");
+ std::string attr;
+ bool r = client::parse_cpp_comment(comment.begin(), comment.end(), attr);
+
+ std::cout << "Parsing a C++ comment";
+ if (r && attr == " This is a comment")
+ std::cout << " succeeded." << std::endl;
+ else
+ std::cout << " failed" << std::endl;
+
+ // C comment
+ comment = "/* This is another comment */";
+ attr.clear();
+ r = client::parse_c_comment(comment.begin(), comment.end(), attr);
+
+ std::cout << "Parsing a C comment";
+ if (r && attr == " This is another comment ")
+ std::cout << " succeeded." << std::endl;
+ else
+ std::cout << " failed" << std::endl;
+
+ // Tagged data
+ std::string data = "<b> This is the body. </b>";
+ attr.clear();
+
+ r = client::parse_tagged(data.begin(), data.end(), attr);
+
+ std::cout << "Parsing tagged data";
+ if (r && attr == "This is the body. ")
+ std::cout << " succeeded." << std::endl;
+ else
+ std::cout << " failed" << std::endl;
+
+ return 0;
+}
+
diff --git a/src/boost/libs/spirit/repository/example/qi/derived.cpp b/src/boost/libs/spirit/repository/example/qi/derived.cpp
new file mode 100644
index 00000000..a92490a9
--- /dev/null
+++ b/src/boost/libs/spirit/repository/example/qi/derived.cpp
@@ -0,0 +1,158 @@
+/*=============================================================================
+ Copyright (c) 2011 Thomas Bernard
+ http://spirit.sourceforge.net/
+
+ 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)
+=============================================================================*/
+//[reference_includes
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/include/phoenix_core.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+#include <boost/spirit/include/phoenix_container.hpp>
+#include <boost/spirit/include/phoenix_object.hpp>
+#include <boost/spirit/include/phoenix_fusion.hpp>
+#include <boost/fusion/include/adapt_struct.hpp>
+#include <boost/spirit/repository/include/qi_kwd.hpp>
+#include <boost/spirit/repository/include/qi_keywords.hpp>
+#include <iostream>
+#include <string>
+#include <cstdlib>
+#include <iterator>
+//]
+
+
+// Data structure definitions
+
+struct base_type {
+ base_type(const std::string &name) : name(name) {}
+ std::string name;
+
+ virtual std::ostream &output(std::ostream &os) const
+ {
+ os<<"Base : "<<name;
+ return os;
+ }
+
+};
+
+struct derived1 : public base_type {
+ derived1(const std::string &name, unsigned int data1) : base_type(name), data1(data1) {}
+ unsigned int data1;
+
+ virtual std::ostream &output(std::ostream &os) const
+ {
+ base_type::output(os);
+ os<<", "<<data1;
+ return os;
+ }
+
+};
+
+struct derived2 : public base_type {
+ derived2(const std::string &name, unsigned int data2) : base_type(name), data2(data2) {}
+ unsigned int data2;
+ virtual std::ostream &output(std::ostream &os) const
+ {
+ base_type::output(os);
+ os<<", "<<data2;
+ return os;
+ }
+
+};
+
+struct derived3 : public derived2 {
+ derived3(const std::string &name, unsigned int data2, double data3) :
+ derived2(name,data2),
+ data3(data3) {}
+ double data3;
+
+ virtual std::ostream &output(std::ostream &os) const
+ {
+ derived2::output(os);
+ os<<", "<<data3;
+ return os;
+ }
+
+
+};
+
+std::ostream &operator<<(std::ostream &os, const base_type &obj)
+{
+ return obj.output(os);
+}
+
+BOOST_FUSION_ADAPT_STRUCT( base_type,
+ (std::string, name)
+)
+
+BOOST_FUSION_ADAPT_STRUCT( derived1,
+ (std::string , name)
+ (unsigned int , data1)
+)
+BOOST_FUSION_ADAPT_STRUCT( derived2,
+ (std::string , name)
+ (unsigned int, data2)
+)
+BOOST_FUSION_ADAPT_STRUCT( derived3,
+ (std::string , name)
+ (unsigned int, data2)
+ (double, data3)
+)
+//]
+
+int
+main()
+{
+
+
+ using boost::spirit::repository::qi::kwd;
+ using boost::spirit::qi::inf;
+ using boost::spirit::ascii::space_type;
+ using boost::spirit::ascii::char_;
+ using boost::spirit::qi::double_;
+ using boost::spirit::qi::int_;
+ using boost::spirit::qi::rule;
+ using boost::spirit::_val;
+ using boost::spirit::_1;
+ using boost::spirit::_2;
+ using boost::spirit::_3;
+
+
+ //Rule declarations
+ rule<const char *, std::string(), space_type> parse_string;
+ rule<const char *, std::vector<base_type*>(), space_type> kwd_rule;
+
+ // Our string parsing helper
+ parse_string %= '"'> *(char_-'"') > '"';
+
+ namespace phx=boost::phoenix;
+ //[ kwd rule
+ kwd_rule =
+ kwd("derived1")[ ('=' > parse_string > int_ ) [phx::push_back(_val,phx::new_<derived1>(_1,_2))] ]
+ / kwd("derived2")[ ('=' > parse_string > int_ ) [phx::push_back(_val,phx::new_<derived2>(_1,_2))]]
+ / kwd("derived3")[ ('=' > parse_string > int_ > double_) [phx::push_back(_val,phx::new_<derived3>(_1,_2,_3))] ]
+ ;
+ //]
+
+ using boost::spirit::qi::phrase_parse;
+ using boost::spirit::qi::ascii::space;
+
+ // The result vector
+ std::vector<base_type*> result;
+
+ char const input[]="derived2 = \"object1\" 10 derived3= \"object2\" 40 20.0 ";
+ char const* f(input);
+ char const* l(f + strlen(f));
+
+ if (phrase_parse(f, l, kwd_rule, space,result) && (f == l))
+ std::cout << "ok" << std::endl;
+ else
+ std::cout << "fail" << std::endl;
+
+ using namespace boost::phoenix::arg_names;
+ std::for_each(result.begin(),result.end(),std::cout<<*arg1<<std::endl);
+ // Clean up the vector of pointers
+ std::for_each(result.begin(),result.end(),phx::delete_(arg1));
+ return 0;
+}
diff --git a/src/boost/libs/spirit/repository/example/qi/distinct.cpp b/src/boost/libs/spirit/repository/example/qi/distinct.cpp
new file mode 100644
index 00000000..78bac6ed
--- /dev/null
+++ b/src/boost/libs/spirit/repository/example/qi/distinct.cpp
@@ -0,0 +1,60 @@
+// Copyright (c) 2001-2010 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)
+
+// The purpose of this example is to demonstrate different use cases for the
+// distinct parser.
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+//[qi_distinct_includes
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/repository/include/qi_distinct.hpp>
+//]
+
+//[qi_distinct_namespace
+using namespace boost::spirit;
+using namespace boost::spirit::ascii;
+using boost::spirit::repository::distinct;
+//]
+
+int main()
+{
+ //[qi_distinct_description_ident
+ {
+ std::string str("description ident");
+ std::string::iterator first(str.begin());
+ bool r = qi::phrase_parse(first, str.end()
+ , distinct(alnum | '_')["description"] >> -lit("--") >> +(alnum | '_')
+ , space);
+ BOOST_ASSERT(r && first == str.end());
+ }
+ //]
+
+ //[qi_distinct_description__ident
+ {
+ std::string str("description--ident");
+ std::string::iterator first(str.begin());
+ bool r = qi::phrase_parse(first, str.end()
+ , distinct(alnum | '_')["description"] >> -lit("--") >> +(alnum | '_')
+ , space);
+ BOOST_ASSERT(r && first == str.end());
+ }
+ //]
+
+ //[qi_distinct_description_ident_error
+ {
+ std::string str("description-ident");
+ std::string::iterator first(str.begin());
+ bool r = qi::phrase_parse(first, str.end()
+ , distinct(alnum | '_')["description"] >> -lit("--") >> +(alnum | '_')
+ , space);
+ BOOST_ASSERT(!r && first == str.begin());
+ }
+ //]
+
+ return 0;
+}
diff --git a/src/boost/libs/spirit/repository/example/qi/flush_multi_pass.cpp b/src/boost/libs/spirit/repository/example/qi/flush_multi_pass.cpp
new file mode 100644
index 00000000..79fa2e57
--- /dev/null
+++ b/src/boost/libs/spirit/repository/example/qi/flush_multi_pass.cpp
@@ -0,0 +1,98 @@
+// Copyright (c) 2001-2010 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)
+
+// The purpose of this example is to demonstrate a simple use case for the
+// flush_multi_pass parser.
+
+#include <iostream>
+#include <fstream>
+#include <string>
+
+//[qi_flush_multi_pass_includes
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/repository/include/qi_flush_multi_pass.hpp>
+//]
+
+//[qi_flush_multi_pass_namespace
+namespace spirit = boost::spirit;
+using boost::spirit::repository::flush_multi_pass;
+//]
+
+namespace client
+{
+ //[qi_flush_multi_pass_clear_buffer
+ template <typename Iterator, typename Skipper>
+ struct preprocessor : spirit::qi::grammar<Iterator, Skipper>
+ {
+ // This is a simplified preprocessor grammar recognizing
+ //
+ // #define MACRONAME something
+ // #undef MACRONAME
+ //
+ // Its sole purpose is to show an example how to use the
+ // flush_multi_pass parser. At the end of each line no backtracking can
+ // occur anymore so that it's safe to clear all internal buffers in the
+ // multi_pass.
+ preprocessor() : preprocessor::base_type(file)
+ {
+ using spirit::ascii::char_;
+ using spirit::qi::eol;
+ using spirit::qi::lit;
+
+ file =
+ *line
+ ;
+
+ line = ( command | *(char_ - eol) )
+ >> eol
+ >> flush_multi_pass
+ ;
+
+ command =
+ "#define" >> *lit(' ') >> *(char_ - ' ') >> *lit(' ') >> *(char_ - eol)
+ | "#undef" >> *lit(' ') >> *(char_ - eol)
+ ;
+ }
+
+ spirit::qi::rule<Iterator, Skipper> file, line, command;
+ };
+ //]
+}
+
+template <typename Iterator, typename Skipper>
+bool parse(Iterator& first, Iterator end, Skipper const& skipper)
+{
+ client::preprocessor<Iterator, Skipper> g;
+ return boost::spirit::qi::phrase_parse(first, end, g, skipper);
+}
+
+int main()
+{
+ namespace spirit = boost::spirit;
+ using spirit::ascii::char_;
+ using spirit::qi::eol;
+
+ std::ifstream in("flush_multi_pass.txt"); // we get our input from this file
+ if (!in.is_open()) {
+ std::cout << "Could not open input file: 'flush_multi_pass.txt'" << std::endl;
+ return -1;
+ }
+
+ typedef std::istreambuf_iterator<char> base_iterator_type;
+ spirit::multi_pass<base_iterator_type> first =
+ spirit::make_default_multi_pass(base_iterator_type(in));
+ spirit::multi_pass<base_iterator_type> end =
+ spirit::make_default_multi_pass(base_iterator_type());
+
+ bool result = parse(first, end, '#' >> *(char_ - eol) >> eol);
+ if (!result) {
+ std::cout << "Failed parsing input file!" << std::endl;
+ return -2;
+ }
+
+ std::cout << "Successfully parsed input file!" << std::endl;
+ return 0;
+}
+
diff --git a/src/boost/libs/spirit/repository/example/qi/flush_multi_pass.txt b/src/boost/libs/spirit/repository/example/qi/flush_multi_pass.txt
new file mode 100644
index 00000000..46cd92eb
--- /dev/null
+++ b/src/boost/libs/spirit/repository/example/qi/flush_multi_pass.txt
@@ -0,0 +1,8 @@
+# Copyright (c) 2001-2009 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)
+
+#define MACRO foo
+#undef MACRO
+
diff --git a/src/boost/libs/spirit/repository/example/qi/iter_pos_parser.cpp b/src/boost/libs/spirit/repository/example/qi/iter_pos_parser.cpp
new file mode 100644
index 00000000..28081405
--- /dev/null
+++ b/src/boost/libs/spirit/repository/example/qi/iter_pos_parser.cpp
@@ -0,0 +1,51 @@
+// Copyright (c) 2001-2010 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)
+
+// The purpose of this example is to show how a simple custom primitive parser
+// component can be written. We develop a custom parser exposing the current
+// iterator position as its attribute.
+//
+// For more information see: http://spirit.sourceforge.net/home/?page_id=567
+
+#include <boost/spirit/include/qi_parse_attr.hpp>
+#include <boost/spirit/include/qi_char.hpp>
+#include <boost/spirit/include/qi_operator.hpp>
+#include <boost/spirit/repository/include/qi_iter_pos.hpp>
+
+#include <string>
+
+namespace qi = boost::spirit::qi;
+
+int main()
+{
+ using boost::spirit::repository::qi::iter_pos;
+
+ std::string prefix, suffix; // attributes receiving the
+ std::string::iterator position; // parsed values
+
+ std::string input("prefix1234567");
+ std::string::iterator first = input.begin();
+ bool result =
+ qi::parse(first, input.end()
+ , +qi::alpha >> iter_pos >> +qi::digit
+ , prefix, position, suffix);
+
+ if (result)
+ {
+ std::cout << "-------------------------------- \n";
+ std::cout << "Parsing succeeded\n";
+ std::cout << "prefix is: " << prefix << "\n";
+ std::cout << "suffix is: " << suffix << "\n";
+ std::cout << "position is: " << std::distance(input.begin(), position) << "\n";
+ std::cout << "-------------------------------- \n";
+ }
+ else
+ {
+ std::cout << "-------------------------------- \n";
+ std::cout << "Parsing failed\n";
+ std::cout << "-------------------------------- \n";
+ }
+ return 0;
+}
diff --git a/src/boost/libs/spirit/repository/example/qi/keywords.cpp b/src/boost/libs/spirit/repository/example/qi/keywords.cpp
new file mode 100644
index 00000000..51ea7353
--- /dev/null
+++ b/src/boost/libs/spirit/repository/example/qi/keywords.cpp
@@ -0,0 +1,214 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ 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)
+=============================================================================*/
+//[reference_includes
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/include/phoenix_core.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+#include <boost/fusion/include/adapt_struct.hpp>
+#include <boost/spirit/repository/include/qi_kwd.hpp>
+#include <boost/spirit/repository/include/qi_keywords.hpp>
+#include <iostream>
+#include <string>
+#include <cstdlib>
+#include <iterator>
+//]
+
+//[reference_test
+template <typename P>
+void test_parser(
+ char const* input, P const& p, bool full_match = true)
+{
+ using boost::spirit::qi::parse;
+
+ char const* f(input);
+ char const* l(f + strlen(f));
+ if (parse(f, l, p) && (!full_match || (f == l)))
+ std::cout << "ok" << std::endl;
+ else
+ std::cout << "fail" << std::endl;
+}
+
+template <typename P>
+void test_phrase_parser(
+ char const* input, P const& p, bool full_match = true)
+{
+ using boost::spirit::qi::phrase_parse;
+ using boost::spirit::qi::ascii::space;
+
+ char const* f(input);
+ char const* l(f + strlen(f));
+ if (phrase_parse(f, l, p, space) && (!full_match || (f == l)))
+ std::cout << "ok" << std::endl;
+ else
+ std::cout << "fail" << std::endl;
+}
+//]
+
+//[reference_test_attr
+template <typename P, typename T>
+void test_parser_attr(
+ char const* input, P const& p, T& attr, bool full_match = true)
+{
+ using boost::spirit::qi::parse;
+
+ char const* f(input);
+ char const* l(f + strlen(f));
+ if (parse(f, l, p, attr) && (!full_match || (f == l)))
+ std::cout << "ok" << std::endl;
+ else
+ std::cout << "fail" << std::endl;
+}
+
+template <typename P, typename T>
+void test_phrase_parser_attr(
+ char const* input, P const& p, T& attr, bool full_match = true)
+{
+ using boost::spirit::qi::phrase_parse;
+ using boost::spirit::qi::ascii::space;
+
+ char const* f(input);
+ char const* l(f + strlen(f));
+ if (phrase_parse(f, l, p, space, attr) && (!full_match || (f == l)))
+ std::cout << "ok" << std::endl;
+ else
+ std::cout << "fail" << std::endl;
+}
+//]
+
+
+
+//[reference_keyword_list_test_data_structure
+// Data structure definitions to test the kwd directive
+// and the keywords list operator
+
+struct person {
+ std::string name;
+ int age;
+ double size;
+ std::vector<std::string> favorite_colors;
+
+};
+
+std::ostream &operator<<(std::ostream &os, const person &p)
+{
+ os<<"Person : "<<p.name<<", "<<p.age<<", "<<p.size<<std::endl;
+ std::copy(p.favorite_colors.begin(),p.favorite_colors.end(),std::ostream_iterator<std::string>(os,"\n"));
+ return os;
+}
+
+BOOST_FUSION_ADAPT_STRUCT( person,
+ (std::string, name)
+ (int, age)
+ (double, size)
+ (std::vector<std::string>, favorite_colors)
+)
+//]
+
+int
+main()
+{
+
+ // keyword_list
+ {
+ //[reference_using_declarations_keyword_list
+ using boost::spirit::repository::qi::kwd;
+ using boost::spirit::qi::inf;
+ using boost::spirit::ascii::space_type;
+ using boost::spirit::ascii::char_;
+ using boost::spirit::qi::double_;
+ using boost::spirit::qi::int_;
+ using boost::spirit::qi::rule;
+ //]
+
+ //[reference_keyword_list_rule_declarations
+ rule<const char *, std::string(), space_type> parse_string;
+ rule<const char *, person(), space_type> no_constraint_person_rule, constraint_person_rule;
+
+ parse_string %= '"'> *(char_-'"') > '"';
+ //]
+
+ //[reference_keyword_list_no_constraint_rule
+ no_constraint_person_rule %=
+ kwd("name")['=' > parse_string ]
+ / kwd("age") ['=' > int_]
+ / kwd("size") ['=' > double_ > 'm']
+ ;
+ //]
+
+
+ //[reference_keyword_list
+ //`Parsing a keyword list:
+ // Let's declare a small list of people for which we want to collect information.
+ person John,Mary,Mike,Hellen,Johny;
+ test_phrase_parser_attr(
+ "name = \"John\" \n age = 10 \n size = 1.69m "
+ ,no_constraint_person_rule
+ ,John); // full in orginal order
+ std::cout<<John;
+
+ test_phrase_parser_attr(
+ "age = 10 \n size = 1.69m \n name = \"Mary\""
+ ,no_constraint_person_rule
+ ,Mary); // keyword oder doesn't matter
+ std::cout<<Mary;
+
+ test_phrase_parser_attr(
+ "size = 1.69m \n name = \"Mike\" \n age = 10 "
+ ,no_constraint_person_rule
+ ,Mike); // still the same result
+
+ std::cout<<Mike;
+
+ /*`The code above will print:[teletype]
+
+ Person : John, 10, 1.69
+ Person : Mary, 10, 1.69
+ Person : Mike, 10, 1.69
+ */
+ //]
+
+ //[reference_keyword_list_constraint_rule
+ /*`The parser definition below uses the kwd directive occurrence constraint variants to
+ make sure that the name and age keyword occur only once and allows the favorite color
+ entry to appear 0 or more times. */
+ constraint_person_rule %=
+ kwd("name",1) ['=' > parse_string ]
+ / kwd("age" ,1) ['=' > int_]
+ / kwd("size" ,1) ['=' > double_ > 'm']
+ / kwd("favorite color",0,inf) [ '=' > parse_string ]
+ ;
+ //]
+
+ //[reference_keyword_list_constraints
+
+ // Here all the give constraint are resepected : parsing will succeed.
+ test_phrase_parser_attr(
+ "name = \"Hellen\" \n age = 10 \n size = 1.80m \n favorite color = \"blue\" \n favorite color = \"green\" "
+ ,constraint_person_rule
+ ,Hellen);
+ std::cout<<Hellen;
+
+ // Parsing this string will fail because the age and size minimum occurrence requirements aren't met.
+ test_phrase_parser_attr(
+ "name = \"Johny\" \n favorite color = \"blue\" \n favorite color = \"green\" "
+ ,constraint_person_rule
+ ,Johny );
+
+ /*`Parsing the first string will succeed but fail for the second string as the
+ occurrence constraints aren't met. This code should print:[teletype]
+
+ Person : Hellen, 10, 1.8
+ blue
+ green
+ */
+ //]
+ }
+
+
+ return 0;
+}
diff --git a/src/boost/libs/spirit/repository/example/qi/mini_xml2_sr.cpp b/src/boost/libs/spirit/repository/example/qi/mini_xml2_sr.cpp
new file mode 100644
index 00000000..a0d2f3a4
--- /dev/null
+++ b/src/boost/libs/spirit/repository/example/qi/mini_xml2_sr.cpp
@@ -0,0 +1,246 @@
+/*=============================================================================
+ Copyright (c) 2001-2010 Joel de Guzman
+ Copyright (c) 2009 Francois Barel
+
+ 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// A mini XML-like parser
+//
+// [ JDG March 25, 2007 ] spirit2
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include <boost/config/warning_disable.hpp>
+//[mini_xml2_sr_includes
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/repository/include/qi_subrule.hpp>
+#include <boost/spirit/include/phoenix_core.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+//]
+#include <boost/spirit/include/phoenix_fusion.hpp>
+#include <boost/spirit/include/phoenix_stl.hpp>
+#include <boost/fusion/include/adapt_struct.hpp>
+#include <boost/variant/recursive_variant.hpp>
+#include <boost/foreach.hpp>
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <vector>
+
+namespace client
+{
+ namespace fusion = boost::fusion;
+ namespace phoenix = boost::phoenix;
+ //[mini_xml2_sr_using
+ namespace qi = boost::spirit::qi;
+ namespace repo = boost::spirit::repository;
+ namespace ascii = boost::spirit::ascii;
+ //]
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Our mini XML tree representation
+ ///////////////////////////////////////////////////////////////////////////
+ struct mini_xml;
+
+ typedef
+ boost::variant<
+ boost::recursive_wrapper<mini_xml>
+ , std::string
+ >
+ mini_xml_node;
+
+ struct mini_xml
+ {
+ std::string name; // tag name
+ std::vector<mini_xml_node> children; // children
+ };
+}
+
+// We need to tell fusion about our mini_xml struct
+// to make it a first-class fusion citizen
+BOOST_FUSION_ADAPT_STRUCT(
+ client::mini_xml,
+ (std::string, name)
+ (std::vector<client::mini_xml_node>, children)
+)
+
+namespace client
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Print out the mini xml tree
+ ///////////////////////////////////////////////////////////////////////////
+ int const tabsize = 4;
+
+ void tab(int indent)
+ {
+ for (int i = 0; i < indent; ++i)
+ std::cout << ' ';
+ }
+
+ struct mini_xml_printer
+ {
+ mini_xml_printer(int indent = 0)
+ : indent(indent)
+ {
+ }
+
+ void operator()(mini_xml const& xml) const;
+
+ int indent;
+ };
+
+ struct mini_xml_node_printer : boost::static_visitor<>
+ {
+ mini_xml_node_printer(int indent = 0)
+ : indent(indent)
+ {
+ }
+
+ void operator()(mini_xml const& xml) const
+ {
+ mini_xml_printer(indent+tabsize)(xml);
+ }
+
+ void operator()(std::string const& text) const
+ {
+ tab(indent+tabsize);
+ std::cout << "text: \"" << text << '"' << std::endl;
+ }
+
+ int indent;
+ };
+
+ void mini_xml_printer::operator()(mini_xml const& xml) const
+ {
+ tab(indent);
+ std::cout << "tag: " << xml.name << std::endl;
+ tab(indent);
+ std::cout << '{' << std::endl;
+
+ BOOST_FOREACH(mini_xml_node const& node, xml.children)
+ {
+ boost::apply_visitor(mini_xml_node_printer(indent), node);
+ }
+
+ tab(indent);
+ std::cout << '}' << std::endl;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Our mini XML grammar definition
+ ///////////////////////////////////////////////////////////////////////////
+ //[mini_xml2_sr_grammar
+ template <typename Iterator>
+ struct mini_xml_grammar
+ : qi::grammar<Iterator, mini_xml(), ascii::space_type>
+ {
+ mini_xml_grammar()
+ : mini_xml_grammar::base_type(entry)
+ {
+ using qi::lit;
+ using qi::lexeme;
+ using ascii::char_;
+ using ascii::string;
+ using namespace qi::labels;
+
+ entry %= (
+ xml %=
+ start_tag[_a = _1]
+ >> *node
+ >> end_tag(_a)
+
+ , node %= xml | text
+
+ , text %= lexeme[+(char_ - '<')]
+
+ , start_tag %=
+ '<'
+ >> !lit('/')
+ >> lexeme[+(char_ - '>')]
+ >> '>'
+
+ , end_tag %=
+ "</"
+ >> lit(_r1)
+ >> '>'
+ );
+ }
+
+ qi::rule<Iterator, mini_xml(), ascii::space_type> entry;
+
+ repo::qi::subrule<0, mini_xml(), qi::locals<std::string> > xml;
+ repo::qi::subrule<1, mini_xml_node()> node;
+ repo::qi::subrule<2, std::string()> text;
+ repo::qi::subrule<3, std::string()> start_tag;
+ repo::qi::subrule<4, void(std::string)> end_tag;
+ };
+ //]
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Main program
+///////////////////////////////////////////////////////////////////////////////
+int main(int argc, char **argv)
+{
+ char const* filename;
+ if (argc > 1)
+ {
+ filename = argv[1];
+ }
+ else
+ {
+ std::cerr << "Error: No input file provided." << std::endl;
+ return 1;
+ }
+
+ std::ifstream in(filename, std::ios_base::in);
+
+ if (!in)
+ {
+ std::cerr << "Error: Could not open input file: "
+ << filename << std::endl;
+ return 1;
+ }
+
+ std::string storage; // We will read the contents here.
+ in.unsetf(std::ios::skipws); // No white space skipping!
+ std::copy(
+ std::istream_iterator<char>(in),
+ std::istream_iterator<char>(),
+ std::back_inserter(storage));
+
+ typedef client::mini_xml_grammar<std::string::const_iterator> mini_xml_grammar;
+ mini_xml_grammar xml; // Our grammar
+ client::mini_xml ast; // Our tree
+
+ using boost::spirit::ascii::space;
+ std::string::const_iterator iter = storage.begin();
+ std::string::const_iterator end = storage.end();
+ bool r = phrase_parse(iter, end, xml, space, ast);
+
+ if (r && iter == end)
+ {
+ std::cout << "-------------------------\n";
+ std::cout << "Parsing succeeded\n";
+ std::cout << "-------------------------\n";
+ client::mini_xml_printer printer;
+ printer(ast);
+ return 0;
+ }
+ else
+ {
+ std::string::const_iterator some = iter + std::min(30, int(end - iter));
+ std::string context(iter, (some>end)?end:some);
+ std::cout << "-------------------------\n";
+ std::cout << "Parsing failed\n";
+ std::cout << "stopped at: \"" << context << "...\"\n";
+ std::cout << "-------------------------\n";
+ return 1;
+ }
+}
+
+
diff --git a/src/boost/libs/spirit/repository/example/qi/options.cpp b/src/boost/libs/spirit/repository/example/qi/options.cpp
new file mode 100644
index 00000000..3bad27c2
--- /dev/null
+++ b/src/boost/libs/spirit/repository/example/qi/options.cpp
@@ -0,0 +1,122 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ 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)
+=============================================================================*/
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/include/karma.hpp>
+#include <boost/fusion/include/adapt_struct.hpp>
+#include <boost/spirit/repository/include/qi_kwd.hpp>
+#include <boost/spirit/repository/include/qi_keywords.hpp>
+#include <boost/optional.hpp>
+#include <boost/cstdint.hpp>
+#include <iostream>
+#include <string>
+#include <cstdlib>
+#include <iterator>
+#include <map>
+#include <vector>
+
+// Data structure definitions
+
+// preprocessor constants
+typedef std::pair<std::string, boost::int32_t> preprocessor_symbol;
+
+BOOST_FUSION_ADAPT_STRUCT( preprocessor_symbol,
+ (std::string, first)
+ (boost::int32_t, second)
+)
+
+// A data structure to store our program options
+struct program_options {
+ std::vector<std::string> includes; // include paths
+ typedef std::vector< preprocessor_symbol > preprocessor_symbols_container; // symbol container type definition
+ preprocessor_symbols_container preprocessor_symbols; // preprocessor symbols
+ boost::optional<std::string> output_filename; // output file name
+ std::string source_filename; // source file name
+
+};
+
+// Make the program_options compatible with fusion sequences
+BOOST_FUSION_ADAPT_STRUCT( program_options,
+ (std::vector<std::string>, includes)
+ (program_options::preprocessor_symbols_container, preprocessor_symbols)
+ (boost::optional<std::string>, output_filename)
+ (std::string, source_filename)
+)
+
+
+// Output helper to check that the data parsed matches what we expect
+std::ostream &operator<<(std::ostream &os, const program_options &obj)
+{
+ using boost::spirit::karma::string;
+ using boost::spirit::karma::int_;
+ using boost::spirit::karma::lit;
+ using boost::spirit::karma::buffer;
+ using boost::spirit::karma::eol;
+ using boost::spirit::karma::format;
+ return os<<format(
+ lit("Includes:") << (string % ',') << eol
+ << lit("Preprocessor symbols:") << ((string <<"="<< int_) % ',') << eol
+ << buffer[-( lit("Output file:")<< string << eol)]
+ << lit("Source file:")<< string << eol
+ ,obj);
+ return os;
+}
+
+
+int
+main()
+{
+
+ {
+ // Pull everything we need from qi into this scope
+ using boost::spirit::repository::qi::kwd;
+ using boost::spirit::qi::inf;
+ using boost::spirit::ascii::space_type;
+ using boost::spirit::ascii::alnum;
+ using boost::spirit::qi::int_;
+ using boost::spirit::qi::rule;
+ using boost::spirit::qi::lit;
+ using boost::spirit::qi::attr;
+ using boost::spirit::qi::lexeme;
+ using boost::spirit::qi::hold;
+ using boost::spirit::qi::ascii::space;
+
+ //Rule declarations
+ rule<const char *, std::string(), space_type> parse_string;
+ rule<const char *, program_options(), space_type> kwd_rule;
+
+ // A string parser
+ parse_string %= lexeme[*alnum];
+
+ namespace phx=boost::phoenix;
+ // kwd rule
+ kwd_rule %=
+ kwd("--include")[ parse_string ]
+ / kwd("--define")[ parse_string >> ((lit('=') > int_) | attr(1)) ]
+ / kwd("--output",0,1)[ parse_string ]
+ / hold [kwd("--source",1)[ parse_string ]]
+ ;
+ //
+
+ using boost::spirit::qi::phrase_parse;
+
+ // Let's check what that parser can do
+ program_options result;
+
+ char const input[]="--include path1 --source file1 --define SYMBOL1=10 --include path2 --source file2";
+ char const* f(input);
+ char const* l(f + strlen(f));
+ if (phrase_parse(f, l, kwd_rule, space,result) && (f == l))
+ std::cout << "ok" << std::endl;
+ else
+ std::cout << "fail" << std::endl;
+
+ // Output the result to the console
+ std::cout<<result<<std::endl;
+}
+ return 0;
+}
diff --git a/src/boost/libs/spirit/repository/example/qi/seek.cpp b/src/boost/libs/spirit/repository/example/qi/seek.cpp
new file mode 100644
index 00000000..c33bc1f3
--- /dev/null
+++ b/src/boost/libs/spirit/repository/example/qi/seek.cpp
@@ -0,0 +1,48 @@
+/*//////////////////////////////////////////////////////////////////////////////
+ Copyright (c) 2011 Jamboree
+
+ 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)
+//////////////////////////////////////////////////////////////////////////////*/
+
+// [ Jamboree Oct 27, 2011 ] new example.
+
+
+#include <cstdlib>
+#include <iostream>
+
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/repository/include/qi_seek.hpp>
+
+
+int main()
+{
+ //[reference_qi_seek_namespace
+ namespace qi = boost::spirit::qi;
+ namespace repo = boost::spirit::repository;
+ //]
+
+ typedef std::string::const_iterator iterator;
+
+ //[reference_qi_seek_vars
+ std::string str("/*C-style comment*/");
+ iterator it = str.begin();
+ iterator end = str.end();
+ //]
+
+ //[reference_qi_seek_parse
+ if (qi::parse(it, end, "/*" >> repo::qi::seek["*/"]))
+ {
+ std::cout << "-------------------------------- \n";
+ std::cout << "Parsing succeeded.\n";
+ std::cout << "---------------------------------\n";
+ }
+ else
+ {
+ std::cout << "-------------------------------- \n";
+ std::cout << "Unterminated /* comment.\n";
+ std::cout << "-------------------------------- \n";
+ }//]
+
+ return EXIT_SUCCESS;
+}
diff --git a/src/boost/libs/spirit/repository/index.html b/src/boost/libs/spirit/repository/index.html
new file mode 100644
index 00000000..1eb81150
--- /dev/null
+++ b/src/boost/libs/spirit/repository/index.html
@@ -0,0 +1,15 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+ <head>
+ <meta http-equiv="refresh" content="0; URL=doc/html/index.html">
+ </head>
+ <body>
+ Automatic redirection failed, click this
+ <a href="doc/html/index.html">link</a> &nbsp;<hr>
+ <p>© Copyright Beman Dawes, 2001</p>
+ <p>Distributed under the Boost Software License, Version 1.0. (See
+ accompanying file <a href="../../LICENSE_1_0.txt">
+ LICENSE_1_0.txt</a> or copy at
+ <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
+ </body>
+</html> \ No newline at end of file
diff --git a/src/boost/libs/spirit/repository/meta/libraries.json b/src/boost/libs/spirit/repository/meta/libraries.json
new file mode 100644
index 00000000..83d22efa
--- /dev/null
+++ b/src/boost/libs/spirit/repository/meta/libraries.json
@@ -0,0 +1,18 @@
+{
+ "key": "spirit/repository",
+ "name": "Spirit Repository",
+ "authors": [
+ "Joel de Guzman",
+ "Hartmut Kaiser",
+ "Dan Nuffer"
+ ],
+ "description": "The Spirit repository is a community effort collecting different reusable components (primitives, directives, grammars, etc.) for Qi parsers and Karma generators.",
+ "category": [
+ "Parsing",
+ "String"
+ ],
+ "maintainers": [
+ "Joel de Guzman <joel -at- boost-consulting.com>",
+ "Hartmut Kaiser <hartmut.kaiser -at- gmail.com>"
+ ]
+}
diff --git a/src/boost/libs/spirit/repository/test/Jamfile b/src/boost/libs/spirit/repository/test/Jamfile
new file mode 100644
index 00000000..18cf1774
--- /dev/null
+++ b/src/boost/libs/spirit/repository/test/Jamfile
@@ -0,0 +1,56 @@
+#==============================================================================
+# Copyright (c) 2001-2009 Joel de Guzman
+# Copyright (c) 2001-2009 Hartmut Kaiser
+# Copyright (c) 2017-2019 Nikita Kniazev
+#
+# Use, modification and distribution is subject to 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)
+#==============================================================================
+project spirit_v2_repository/test
+ : requirements
+ <include>.
+ <c++-template-depth>300
+ :
+ :
+ ;
+
+###############################################################################
+
+alias qi-pch : : <pch>on-spirit:<source>../../test/qi//pch ;
+alias ka-pch : : <pch>on-spirit:<source>../../test/karma//pch ;
+explicit qi-pch ka-pch ;
+
+###############################################################################
+
+import os ;
+
+local keywords_reqs ;
+
+if [ os.environ APPVEYOR ]
+{
+ # Workaround MSVC codegen bug. See #400 for the info.
+ keywords_reqs = <toolset>msvc-14.1:<inlining>off ;
+}
+
+# bring in rules for testing
+import testing ;
+
+{
+ test-suite spirit_v2_repository :
+
+ # run Qi repository tests
+ [ run qi-pch qi/advance.cpp : : : : qi_repo_advance ]
+ [ run qi-pch qi/confix.cpp : : : : qi_repo_confix ]
+ [ run qi-pch qi/distinct.cpp : : : : qi_repo_distinct ]
+ [ run qi-pch qi/subrule.cpp : : : : qi_repo_subrule ]
+ [ run qi-pch qi/keywords.cpp : : : $(keywords_reqs) : qi_repo_keywords ]
+ [ run qi-pch qi/seek.cpp : : : : qi_repo_seek ]
+
+ # run Karma repository tests
+ [ run ka-pch karma/confix.cpp : : : : karma_repo_confix ]
+ [ run ka-pch karma/subrule.cpp : : : : karma_repo_subrule ]
+
+ ;
+}
+
diff --git a/src/boost/libs/spirit/repository/test/karma/confix.cpp b/src/boost/libs/spirit/repository/test/karma/confix.cpp
new file mode 100644
index 00000000..adbe9903
--- /dev/null
+++ b/src/boost/libs/spirit/repository/test/karma/confix.cpp
@@ -0,0 +1,123 @@
+// Copyright (c) 2001-2010 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)
+
+#include <boost/config/warning_disable.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/include/karma_auxiliary.hpp>
+#include <boost/spirit/include/karma_char.hpp>
+#include <boost/spirit/include/karma_string.hpp>
+#include <boost/spirit/include/karma_generate.hpp>
+
+#include <boost/spirit/repository/include/karma_confix.hpp>
+
+#include <iostream>
+#include "test.hpp"
+
+namespace html
+{
+ namespace spirit = boost::spirit;
+ namespace repo = boost::spirit::repository;
+
+ ///////////////////////////////////////////////////////////////////////////////
+ // define a HTML tag helper generator
+ namespace traits
+ {
+ template <typename Prefix, typename Suffix = Prefix>
+ struct confix_spec
+ : spirit::result_of::terminal<repo::tag::confix(Prefix, Suffix)>
+ {};
+ }
+
+ template <typename Prefix, typename Suffix>
+ inline typename traits::confix_spec<Prefix, Suffix>::type
+ confix_spec(Prefix const& prefix, Suffix const& suffix)
+ {
+ return repo::confix(prefix, suffix);
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Char, typename Traits, typename Allocator>
+ inline typename traits::confix_spec<
+ std::basic_string<Char, Traits, Allocator>
+ >::type
+ tag (std::basic_string<Char, Traits, Allocator> const& tagname)
+ {
+ typedef std::basic_string<Char, Traits, Allocator> string_type;
+ return confix_spec(string_type("<") + tagname + ">"
+ , string_type("</") + tagname + ">");
+ }
+
+ inline traits::confix_spec<std::string>::type
+ tag (char const* tagname)
+ {
+ return tag(std::string(tagname));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ typedef traits::confix_spec<std::string>::type html_tag_type;
+
+ html_tag_type const ol = tag("ol");
+}
+
+///////////////////////////////////////////////////////////////////////////////
+int main()
+{
+ using namespace spirit_test;
+ using namespace boost::spirit;
+ using namespace boost::spirit::repository;
+
+ {
+ using namespace boost::spirit::ascii;
+
+ BOOST_TEST((test("<tag>a</tag>",
+ confix("<tag>", "</tag>")[char_('a')])));
+ BOOST_TEST((test("<tag>a</tag>",
+ confix("<tag>", "</tag>")[char_], 'a')));
+ BOOST_TEST((test("// some C++ comment\n",
+ confix(string("//"), eol)[" some C++ comment"])));
+ BOOST_TEST((test("// some C++ comment\n",
+ confix(string("//"), eol)[string], " some C++ comment")));
+
+ BOOST_TEST((test("<ol>some text</ol>", html::ol["some text"])));
+ BOOST_TEST((test("<ol>some text</ol>", html::ol[string], "some text")));
+ }
+
+ {
+ using namespace boost::spirit::standard_wide;
+
+ BOOST_TEST((test(L"<tag>a</tag>",
+ confix(L"<tag>", L"</tag>")[char_(L'a')])));
+ BOOST_TEST((test(L"// some C++ comment\n",
+ confix(string(L"//"), eol)[L" some C++ comment"])));
+
+ BOOST_TEST((test(L"<ol>some text</ol>", html::ol[L"some text"])));
+ }
+
+ {
+ using namespace boost::spirit::ascii;
+
+ BOOST_TEST((test_delimited("<tag> a </tag> ",
+ confix("<tag>", "</tag>")[char_('a')], space)));
+ BOOST_TEST((test_delimited("// some C++ comment \n ",
+ confix(string("//"), eol)["some C++ comment"], space)));
+
+ BOOST_TEST((test_delimited("<ol> some text </ol> ",
+ html::ol["some text"], space)));
+ }
+
+ {
+ using namespace boost::spirit::standard_wide;
+
+ BOOST_TEST((test_delimited(L"<tag> a </tag> ",
+ confix(L"<tag>", L"</tag>")[char_(L'a')], space)));
+ BOOST_TEST((test_delimited(L"// some C++ comment \n ",
+ confix(string(L"//"), eol)[L"some C++ comment"], space)));
+
+ BOOST_TEST((test_delimited(L"<ol> some text </ol> ",
+ html::ol[L"some text"], space)));
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/repository/test/karma/subrule.cpp b/src/boost/libs/spirit/repository/test/karma/subrule.cpp
new file mode 100644
index 00000000..dd6bdabe
--- /dev/null
+++ b/src/boost/libs/spirit/repository/test/karma/subrule.cpp
@@ -0,0 +1,186 @@
+// Copyright (c) 2001-2010 Hartmut Kaiser
+// Copyright (c) 2009 Francois Barel
+//
+// 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)
+
+#include <boost/config/warning_disable.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#include <boost/spirit/include/karma_operator.hpp>
+#include <boost/spirit/include/karma_char.hpp>
+#include <boost/spirit/include/karma_auxiliary.hpp>
+#include <boost/spirit/include/karma_string.hpp>
+#include <boost/spirit/include/karma_numeric.hpp>
+#include <boost/spirit/include/karma_nonterminal.hpp>
+#include <boost/spirit/include/karma_action.hpp>
+#include <boost/spirit/include/phoenix_core.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+#include <boost/spirit/include/phoenix_statement.hpp>
+#include <boost/spirit/include/phoenix_fusion.hpp>
+
+#include <boost/spirit/repository/include/karma_subrule.hpp>
+
+#include "test.hpp"
+
+using namespace spirit_test;
+
+///////////////////////////////////////////////////////////////////////////////
+int main()
+{
+ using namespace boost;
+ using namespace boost::spirit;
+ using namespace boost::spirit::karma;
+// using namespace boost::spirit::ascii;
+ using boost::spirit::repository::karma::subrule;
+
+ typedef spirit_test::output_iterator<char>::type outiter_type;
+
+ // basic tests
+ {
+ rule<outiter_type> start;
+ subrule<0> sr;
+
+ start = (
+ sr = char_[_1 = 'a'] << int_[_1 = 10] << double_[_1 = 12.4]
+ );
+ BOOST_TEST(test("a1012.4", start));
+
+ BOOST_TEST(test("a1012.4", (
+ sr = (char_ << int_ << double_)[_1 = 'a', _2 = 10, _3 = 12.4]
+ )));
+
+ subrule<1> a;
+ subrule<2> b;
+ subrule<3> c;
+
+ start = (
+ sr = a << b << c
+ , a = char_[_1 = 'a']
+ , b = int_[_1 = 10]
+ , c = double_[_1 = 12.4]
+ );
+ BOOST_TEST(test("a1012.4", start));
+ }
+
+ // basic tests with delimiter
+ {
+ rule<outiter_type, space_type> start;
+ subrule<0> sr;
+
+ start = (
+ sr = char_[_1 = 'a'] << int_[_1 = 10] << double_[_1 = 12.4]
+ );
+ BOOST_TEST(test_delimited("a 10 12.4 ", start, space));
+
+ BOOST_TEST(test_delimited("a 10 12.4 ", (
+ sr = (char_ << int_ << double_)[_1 = 'a', _2 = 10, _3 = 12.4]
+ ), space));
+
+ subrule<1> a;
+ subrule<2> b;
+ subrule<3> c;
+
+ start = (
+ sr = a << b << c
+ , a = char_[_1 = 'a']
+ , b = int_[_1 = 10]
+ , c = double_[_1 = 12.4]
+ );
+ BOOST_TEST(test_delimited("a 10 12.4 ", start, space));
+ }
+
+ // basic tests involving a direct parameter
+ {
+ typedef variant<char, int, double> var_type;
+
+ rule<outiter_type, var_type()> start;
+ subrule<0, var_type()> sr;
+
+ start = (
+ sr = (char_ | int_ | double_)[_1 = _r0]
+ )[_1 = _val];
+
+ var_type v ('a');
+ BOOST_TEST(test("a", start, v));
+ v = 10;
+ BOOST_TEST(test("10", start, v));
+ v = 12.4;
+ BOOST_TEST(test("12.4", start, v));
+ }
+
+ {
+ typedef variant<char, int, double> var_type;
+
+ rule<outiter_type, space_type, var_type()> start;
+ subrule<0, var_type()> sr;
+
+ start %= (
+ sr = (char_ | int_ | double_)[_1 = _r0]
+ );
+
+ var_type v ('a');
+ BOOST_TEST(test_delimited("a ", start, v, space));
+ v = 10;
+ BOOST_TEST(test_delimited("10 ", start, v, space));
+ v = 12.4;
+ BOOST_TEST(test_delimited("12.4 ", start, v, space));
+ }
+
+ {
+ rule<outiter_type, void(char, int, double)> start;
+ subrule<0, void(char, int, double)> sr;
+
+ start = (
+ sr = char_[_1 = _r1] << int_[_1 = _r2] << double_[_1 = _r3]
+ )(_r1, _r2, _r3);
+ BOOST_TEST(test("a1012.4", start('a', 10, 12.4)));
+
+ BOOST_TEST(test("a1012.4", (
+ sr = (char_ << int_ << double_)[_1 = _r1, _2 = _r2, _3 = _r3]
+ )('a', 10, 12.4)));
+
+ subrule<1, void(char, int, double)> entry;
+ subrule<2, void(char)> a;
+ subrule<3, void(int)> b;
+ subrule<4, void(double)> c;
+
+ start = (
+ entry = a(_r1) << b(_r2) << c(_r3)
+ , a = char_[_1 = _r1]
+ , b = int_[_1 = _r1]
+ , c = double_[_1 = _r1]
+ )(_r1, _r2, _r3);
+ BOOST_TEST(test("a1012.4", start('a', 10, 12.4)));
+ }
+
+ {
+ rule<outiter_type, space_type, void(char, int, double)> start;
+ subrule<0, void(char, int, double)> sr;
+
+ start = (
+ sr = char_[_1 = _r1] << int_[_1 = _r2] << double_[_1 = _r3]
+ )(_r1, _r2, _r3);
+ BOOST_TEST(test_delimited("a 10 12.4 ", start('a', 10, 12.4), space));
+
+ BOOST_TEST(test_delimited("a 10 12.4 ", (
+ sr = (char_ << int_ << double_)[_1 = _r1, _2 = _r2, _3 = _r3]
+ )('a', 10, 12.4), space));
+
+ subrule<1, void(char, int, double)> entry;
+ subrule<2, void(char)> a;
+ subrule<3, void(int)> b;
+ subrule<4, void(double)> c;
+
+ start = (
+ entry = a(_r1) << b(_r2) << c(_r3)
+ , a = char_[_1 = _r1]
+ , b = int_[_1 = _r1]
+ , c = double_[_1 = _r1]
+ )(_r1, _r2, _r3);
+ BOOST_TEST(test_delimited("a 10 12.4 ", start('a', 10, 12.4), space));
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/spirit/repository/test/karma/test.hpp b/src/boost/libs/spirit/repository/test/karma/test.hpp
new file mode 100644
index 00000000..70b89ce5
--- /dev/null
+++ b/src/boost/libs/spirit/repository/test/karma/test.hpp
@@ -0,0 +1,297 @@
+// Copyright (c) 2001-2010 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_TEST_FEB_23_2007_1221PM)
+#define BOOST_SPIRIT_KARMA_TEST_FEB_23_2007_1221PM
+
+#include <cstring>
+#include <string>
+#include <iterator>
+#include <iostream>
+#include <typeinfo>
+
+#include <boost/spirit/include/karma_generate.hpp>
+#include <boost/spirit/include/karma_what.hpp>
+
+namespace spirit_test
+{
+ ///////////////////////////////////////////////////////////////////////////
+ struct display_type
+ {
+ template<typename T>
+ void operator()(T const &) const
+ {
+ std::cout << typeid(T).name() << std::endl;
+ }
+
+ template<typename T>
+ static void print()
+ {
+ std::cout << typeid(T).name() << std::endl;
+ }
+ };
+
+ display_type const display = {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Char>
+ struct output_iterator
+ {
+ typedef std::basic_string<Char> string_type;
+ typedef std::back_insert_iterator<string_type> type;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Char, typename T>
+ void print_if_failed(char const* func, bool result
+ , std::basic_string<Char> const& generated, T const& expected)
+ {
+ if (!result)
+ std::cerr << "in " << func << ": result is false" << std::endl;
+ else if (generated != expected)
+ std::cerr << "in " << func << ": generated \""
+ << std::string(generated.begin(), generated.end())
+ << "\"" << std::endl;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Char, typename Generator>
+ inline bool test(Char const *expected, Generator const& g)
+ {
+ namespace karma = boost::spirit::karma;
+ typedef std::basic_string<Char> string_type;
+
+ // we don't care about the result of the "what" function.
+ // we only care that all generators have it:
+ karma::what(g);
+
+ string_type generated;
+ std::back_insert_iterator<string_type> outit(generated);
+ bool result = karma::generate(outit, g);
+
+ print_if_failed("test", result, generated, expected);
+ return result && generated == expected;
+ }
+
+ template <typename Char, typename Generator>
+ inline bool test(std::basic_string<Char> const& expected, Generator const& g)
+ {
+ namespace karma = boost::spirit::karma;
+ typedef std::basic_string<Char> string_type;
+
+ // we don't care about the result of the "what" function.
+ // we only care that all generators have it:
+ karma::what(g);
+
+ string_type generated;
+ std::back_insert_iterator<string_type> outit(generated);
+ bool result = karma::generate(outit, g);
+
+ print_if_failed("test", result, generated, expected);
+ return result && generated == expected;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Char, typename Generator, typename Attribute>
+ inline bool test(Char const *expected, Generator const& g,
+ Attribute const &attr)
+ {
+ namespace karma = boost::spirit::karma;
+ typedef std::basic_string<Char> string_type;
+
+ // we don't care about the result of the "what" function.
+ // we only care that all generators have it:
+ karma::what(g);
+
+ string_type generated;
+ std::back_insert_iterator<string_type> outit(generated);
+ bool result = karma::generate(outit, g, attr);
+
+ print_if_failed("test", result, generated, expected);
+ return result && generated == expected;
+ }
+
+ template <typename Char, typename Generator, typename Attribute>
+ inline bool test(std::basic_string<Char> const& expected, Generator const& g,
+ Attribute const &attr)
+ {
+ namespace karma = boost::spirit::karma;
+ typedef std::basic_string<Char> string_type;
+
+ // we don't care about the result of the "what" function.
+ // we only care that all generators have it:
+ karma::what(g);
+
+ string_type generated;
+ std::back_insert_iterator<string_type> outit(generated);
+ bool result = karma::generate(outit, g, attr);
+
+ print_if_failed("test", result, generated, expected);
+ return result && generated == expected;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Char, typename Generator, typename Delimiter>
+ inline bool test_delimited(Char const *expected, Generator const& g,
+ Delimiter const& d)
+ {
+ namespace karma = boost::spirit::karma;
+ typedef std::basic_string<Char> string_type;
+
+ // we don't care about the result of the "what" function.
+ // we only care that all generators have it:
+ karma::what(g);
+
+ string_type generated;
+ std::back_insert_iterator<string_type> outit(generated);
+ bool result = karma::generate_delimited(outit, g, d);
+
+ print_if_failed("test_delimited", result, generated, expected);
+ return result && generated == expected;
+ }
+
+ template <typename Char, typename Generator, typename Delimiter>
+ inline bool test_delimited(std::basic_string<Char> const& expected,
+ Generator const& g, Delimiter const& d)
+ {
+ namespace karma = boost::spirit::karma;
+ typedef std::basic_string<Char> string_type;
+
+ // we don't care about the result of the "what" function.
+ // we only care that all generators have it:
+ karma::what(g);
+
+ string_type generated;
+ std::back_insert_iterator<string_type> outit(generated);
+ bool result = karma::generate_delimited(outit, g, d);
+
+ print_if_failed("test_delimited", result, generated, expected);
+ return result && generated == expected;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Char, typename Generator, typename Attribute,
+ typename Delimiter>
+ inline bool test_delimited(Char const *expected, Generator const& g,
+ Attribute const &attr, Delimiter const& d)
+ {
+ namespace karma = boost::spirit::karma;
+ typedef std::basic_string<Char> string_type;
+
+ // we don't care about the result of the "what" function.
+ // we only care that all generators have it:
+ karma::what(g);
+
+ string_type generated;
+ std::back_insert_iterator<string_type> outit(generated);
+ bool result = karma::generate_delimited(outit, g, d, attr);
+
+ print_if_failed("test_delimited", result, generated, expected);
+ return result && generated == expected;
+ }
+
+ template <typename Char, typename Generator, typename Attribute,
+ typename Delimiter>
+ inline bool test_delimited(std::basic_string<Char> const& expected,
+ Generator const& g, Attribute const &attr, Delimiter const& d)
+ {
+ namespace karma = boost::spirit::karma;
+ typedef std::basic_string<Char> string_type;
+
+ // we don't care about the result of the "what" function.
+ // we only care that all generators have it:
+ karma::what(g);
+
+ string_type generated;
+ std::back_insert_iterator<string_type> outit(generated);
+ bool result = karma::generate_delimited(outit, g, d, attr);
+
+ print_if_failed("test_delimited", result, generated, expected);
+ return result && generated == expected;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Generator>
+ inline bool
+ binary_test(char const *expected, std::size_t size,
+ Generator const& g)
+ {
+ namespace karma = boost::spirit::karma;
+ typedef std::basic_string<char> string_type;
+
+ // we don't care about the result of the "what" function.
+ // we only care that all generators have it:
+ karma::what(g);
+
+ string_type generated;
+ std::back_insert_iterator<string_type> outit(generated);
+ bool result = karma::generate(outit, g);
+
+ return result && !std::memcmp(generated.c_str(), expected, size);
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Generator, typename Attribute>
+ inline bool
+ binary_test(char const *expected, std::size_t size,
+ Generator const& g, Attribute const &attr)
+ {
+ namespace karma = boost::spirit::karma;
+ typedef std::basic_string<char> string_type;
+
+ // we don't care about the result of the "what" function.
+ // we only care that all generators have it:
+ karma::what(g);
+
+ string_type generated;
+ std::back_insert_iterator<string_type> outit(generated);
+ bool result = karma::generate(outit, g, attr);
+
+ return result && !std::memcmp(generated.c_str(), expected, size);
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Generator, typename Delimiter>
+ inline bool
+ binary_test_delimited(char const *expected, std::size_t size,
+ Generator const& g, Delimiter const& d)
+ {
+ namespace karma = boost::spirit::karma;
+ typedef std::basic_string<char> string_type;
+
+ // we don't care about the result of the "what" function.
+ // we only care that all generators have it:
+ karma::what(g);
+
+ string_type generated;
+ std::back_insert_iterator<string_type> outit(generated);
+ bool result = karma::generate_delimited(outit, g, d);
+
+ return result && !std::memcmp(generated.c_str(), expected, size);
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Generator, typename Attribute, typename Delimiter>
+ inline bool
+ binary_test_delimited(char const *expected, std::size_t size,
+ Generator const& g, Attribute const &attr, Delimiter const& d)
+ {
+ namespace karma = boost::spirit::karma;
+ typedef std::basic_string<char> string_type;
+
+ // we don't care about the result of the "what" function.
+ // we only care that all generators have it:
+ karma::what(g);
+
+ string_type generated;
+ std::back_insert_iterator<string_type> outit(generated);
+ bool result = karma::generate_delimited(outit, g, d, attr);
+
+ return result && !std::memcmp(generated.c_str(), expected, size);
+ }
+
+} // namespace spirit_test
+
+#endif // !BOOST_SPIRIT_KARMA_TEST_FEB_23_2007_1221PM
diff --git a/src/boost/libs/spirit/repository/test/qi/advance.cpp b/src/boost/libs/spirit/repository/test/qi/advance.cpp
new file mode 100644
index 00000000..160ac55f
--- /dev/null
+++ b/src/boost/libs/spirit/repository/test/qi/advance.cpp
@@ -0,0 +1,111 @@
+// Copyright (c) 2001-2010 Hartmut Kaiser
+// Copyright (c) 2001-2010 Joel de Guzman
+// Copyright (c) 2011 Aaron Graham
+//
+// 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)
+
+#include <boost/detail/lightweight_test.hpp>
+
+#include <boost/spirit/include/qi_action.hpp>
+#include <boost/spirit/include/qi_auxiliary.hpp>
+#include <boost/spirit/include/qi_binary.hpp>
+#include <boost/spirit/include/qi_char.hpp>
+#include <boost/spirit/include/qi_directive.hpp>
+#include <boost/spirit/include/qi_nonterminal.hpp>
+#include <boost/spirit/include/qi_numeric.hpp>
+#include <boost/spirit/include/qi_operator.hpp>
+#include <boost/spirit/include/qi_string.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+
+#include <boost/spirit/repository/include/qi_advance.hpp>
+
+#include <boost/assign/std/list.hpp>
+#include "test.hpp"
+
+namespace spirit_test
+{
+ template <typename Container, typename Parser>
+ bool test_c(Container const& in, Parser const& p, bool full_match = true)
+ {
+ // we don't care about the results of the "what" function.
+ // we only care that all parsers have it:
+ boost::spirit::qi::what(p);
+
+ typename Container::const_iterator first = in.begin();
+ typename Container::const_iterator const last = in.end();
+ return boost::spirit::qi::parse(first, last, p)
+ && (!full_match || (first == last));
+ }
+}
+
+int main()
+{
+ using spirit_test::test;
+ using spirit_test::test_c;
+
+ using namespace boost::spirit::qi::labels;
+ using boost::spirit::qi::locals;
+ using boost::spirit::qi::rule;
+ using boost::spirit::qi::uint_;
+ using boost::spirit::qi::byte_;
+
+ using namespace boost::assign;
+ using boost::spirit::repository::qi::advance;
+
+ { // test basic functionality with random-access iterators
+ rule<char const*> start;
+
+ start = 'a' >> advance(3) >> "bc";
+ BOOST_TEST(test("a123bc", start));
+
+ start = (advance(3) | 'q') >> 'i';
+ BOOST_TEST(test("qi", start));
+
+ start = advance(-1);
+ BOOST_TEST(!test("0", start));
+
+ start = advance(-1) | "qi";
+ BOOST_TEST(test("qi", start));
+
+ start = advance(0) >> "abc" >> advance(10) >> "nopq" >> advance(0)
+ >> advance(8) >> 'z';
+ BOOST_TEST(test("abcdefghijklmnopqrstuvwxyz", start));
+ }
+
+ { // test locals
+ rule<char const*, locals<unsigned> > start;
+
+ start = byte_ [_a = _1] >> advance(_a) >> "345";
+ BOOST_TEST(test("\x02""12345", start));
+ BOOST_TEST(!test("\x60""345", start));
+ }
+
+ { // test basic functionality with bidirectional iterators
+ rule<std::list<char>::const_iterator, locals<int> > start;
+ std::list<char> list;
+
+ list.clear();
+ list += 1,2,'a','b','c';
+ start = byte_ [_a = _1] >> advance(_a) >> "abc";
+ BOOST_TEST(test_c(list, start));
+
+ list.clear();
+ list += 3,'q','i';
+ start = byte_ [_a = _1] >> advance(_a);
+ BOOST_TEST(!test_c(list, start));
+
+ start = byte_ [_a = _1] >> (advance(_a) | "qi");
+ BOOST_TEST(test_c(list, start));
+
+ list.clear();
+ list += 'a','b','c','d','e','f','g','h','i','j','k','l','m';
+ list += 'n','o','p','q','r','s','t','u','v','w','x','y','z';
+ start = advance(0) >> "abc" >> advance(10) >> "nopq" >> advance(0)
+ >> advance(8) >> 'z';
+ BOOST_TEST(test_c(list, start));
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/spirit/repository/test/qi/confix.cpp b/src/boost/libs/spirit/repository/test/qi/confix.cpp
new file mode 100644
index 00000000..e045026c
--- /dev/null
+++ b/src/boost/libs/spirit/repository/test/qi/confix.cpp
@@ -0,0 +1,147 @@
+/*=============================================================================
+ Copyright (c) 2009 Chris Hoeppler
+
+ 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)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+
+#include <boost/spirit/include/qi_action.hpp>
+#include <boost/spirit/include/qi_auxiliary.hpp>
+#include <boost/spirit/include/qi_char.hpp>
+#include <boost/spirit/include/qi_directive.hpp>
+#include <boost/spirit/include/qi_nonterminal.hpp>
+#include <boost/spirit/include/qi_numeric.hpp>
+#include <boost/spirit/include/qi_operator.hpp>
+#include <boost/spirit/include/qi_string.hpp>
+#include <boost/spirit/include/phoenix_bind.hpp>
+#include <boost/spirit/include/phoenix_core.hpp>
+#include <boost/spirit/include/phoenix_object.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+
+#include <boost/spirit/repository/include/qi_confix.hpp>
+
+#include <string>
+#include "test.hpp"
+
+namespace comment {
+ namespace spirit = boost::spirit;
+ namespace repo = boost::spirit::repository;
+
+ // Define a metafunction allowing to compute the type
+ // of the confix() construct
+ template <typename Prefix, typename Suffix = Prefix>
+ struct confix_spec_traits
+ {
+ typedef typename spirit::result_of::terminal<
+ repo::tag::confix(Prefix, Suffix)
+ >::type type;
+ };
+
+ template <typename Prefix, typename Suffix>
+ inline typename confix_spec_traits<Prefix, Suffix>::type
+ confix_spec(Prefix const& prefix, Suffix const& suffix)
+ {
+ return repo::confix(prefix, suffix);
+ }
+
+ inline confix_spec_traits<std::string>::type
+ confix_spec(const char* prefix, const char* suffix)
+ {
+ return repo::confix(std::string(prefix), std::string(suffix));
+ }
+ confix_spec_traits<std::string>::type const c_comment = confix_spec("/*", "*/");
+ confix_spec_traits<std::string>::type const cpp_comment = confix_spec("//", "\n");
+}
+
+int main()
+{
+ using spirit_test::test_attr;
+ using spirit_test::test;
+
+ using namespace boost::spirit::ascii;
+ using namespace boost::spirit::qi::labels;
+ using boost::spirit::qi::locals;
+ using boost::spirit::qi::rule;
+ using boost::spirit::qi::debug;
+
+ namespace phx = boost::phoenix;
+ namespace repo = boost::spirit::repository;
+
+ { // basic tests
+
+ rule<char const*> start;
+
+ start = repo::confix('a', 'c')['b'];
+ BOOST_TEST(test("abc", start));
+
+ start = repo::confix('a', 'c')['b'] | "abd";
+ BOOST_TEST(test("abd", start));
+
+ start = repo::confix("/*", "*/")[*(alpha - "*/")];
+ BOOST_TEST(test("/*aaaabababaaabbb*/", start));
+
+ start = repo::confix(char_('/') >> '*', '*' >> char_('/'))[*alpha - "*/"];
+ BOOST_TEST(test("/*aaaabababaaabba*/", start));
+
+ start = comment::c_comment[*(alpha - "*/")];
+ BOOST_TEST(test("/*aaaabababaaabbb*/", start));
+
+ // ignore the skipper!
+ BOOST_TEST(!test("/* aaaabababaaabba*/", start, space));
+ }
+
+ { // basic tests w/ skipper
+
+ rule<char const*, space_type> start;
+
+ start = repo::confix('a', 'c')['b'];
+ BOOST_TEST(test(" a b c ", start, space));
+
+ start = repo::confix(char_('/') >> '*', '*' >> char_('/'))[*alpha - "*/"];
+ BOOST_TEST(test(" / *a b a b a b a a a b b b * / ", start, space));
+ }
+
+ { // context tests
+ char ch;
+ rule<char const*, char()> a;
+ a = repo::confix("/*", "*/")[alpha][_val = _1];
+
+ BOOST_TEST(test("/*x*/", a[phx::ref(ch) = _1]));
+ BOOST_TEST(ch == 'x');
+
+ a %= repo::confix("/*", "*/")[alpha];
+ BOOST_TEST(test_attr("/*z*/", a, ch)); // attribute is given.
+ BOOST_TEST(ch == 'z');
+ }
+
+ { // rules test
+ rule<char const*> a, b, c, start;
+
+ a = 'a';
+ b = 'b';
+ c = 'c';
+
+ a.name("a");
+ b.name("b");
+ c.name("c");
+ start.name("start");
+
+ debug(a);
+ debug(b);
+ debug(c);
+ debug(start);
+
+ start = repo::confix(a.alias(), c.alias())[b];
+ BOOST_TEST(test("abc", start));
+ }
+
+ { // modifiers test
+ rule<char const*> start;
+ start = no_case[repo::confix("_A_", "_Z_")["heLLo"]];
+ BOOST_TEST(test("_a_hello_z_", start));
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/spirit/repository/test/qi/distinct.cpp b/src/boost/libs/spirit/repository/test/qi/distinct.cpp
new file mode 100644
index 00000000..7ba4c521
--- /dev/null
+++ b/src/boost/libs/spirit/repository/test/qi/distinct.cpp
@@ -0,0 +1,101 @@
+// Copyright (c) 2001-2010 Hartmut Kaiser
+// Copyright (c) 2001-2010 Joel de Guzman
+// Copyright (c) 2003 Vaclav Vesely
+//
+// 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)
+
+#include <boost/mpl/print.hpp>
+#include <boost/config/warning_disable.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/include/qi_char.hpp>
+#include <boost/spirit/include/qi_string.hpp>
+#include <boost/spirit/include/qi_nonterminal.hpp>
+#include <boost/spirit/include/qi_numeric.hpp>
+#include <boost/spirit/include/qi_action.hpp>
+#include <boost/spirit/include/qi_operator.hpp>
+
+#include <boost/spirit/repository/include/qi_distinct.hpp>
+
+#include <iostream>
+#include "test.hpp"
+
+using namespace boost;
+
+///////////////////////////////////////////////////////////////////////////////
+namespace distinct
+{
+ //[qi_distinct_encapsulation
+ namespace spirit = boost::spirit;
+ namespace ascii = boost::spirit::ascii;
+ namespace repo = boost::spirit::repository;
+
+ // Define metafunctions allowing to compute the type of the distinct()
+ // and ascii::char_() constructs
+ namespace traits
+ {
+ // Metafunction allowing to get the type of any repository::distinct(...)
+ // construct
+ template <typename Tail>
+ struct distinct_spec
+ : spirit::result_of::terminal<repo::tag::distinct(Tail)>
+ {};
+
+ // Metafunction allowing to get the type of any ascii::char_(...) construct
+ template <typename String>
+ struct char_spec
+ : spirit::result_of::terminal<spirit::tag::ascii::char_(String)>
+ {};
+ }
+
+ // Define a helper function allowing to create a distinct() construct from
+ // an arbitrary tail parser
+ template <typename Tail>
+ inline typename traits::distinct_spec<Tail>::type
+ distinct_spec(Tail const& tail)
+ {
+ return repo::distinct(tail);
+ }
+
+ // Define a helper function allowing to create a ascii::char_() construct
+ // from an arbitrary string representation
+ template <typename String>
+ inline typename traits::char_spec<String>::type
+ char_spec(String const& str)
+ {
+ return ascii::char_(str);
+ }
+
+ // the following constructs the type of a distinct_spec holding a
+ // charset("0-9a-zA-Z_") as its tail parser
+ typedef traits::char_spec<std::string>::type charset_tag_type;
+ typedef traits::distinct_spec<charset_tag_type>::type keyword_tag_type;
+
+ // Define a new Qi 'keyword' directive usable as a shortcut for a
+ // repository::distinct(char_(std::string("0-9a-zA-Z_")))
+ std::string const keyword_spec("0-9a-zA-Z_");
+ keyword_tag_type const keyword = distinct_spec(char_spec(keyword_spec));
+ //]
+}
+
+///////////////////////////////////////////////////////////////////////////////
+int main()
+{
+ using namespace spirit_test;
+ using namespace boost::spirit;
+
+ {
+ using namespace boost::spirit::ascii;
+
+ qi::rule<char const*, space_type> r;
+ r = distinct::keyword["description"] >> -lit(':') >> distinct::keyword["ident"];
+
+ BOOST_TEST(test("description ident", r, space));
+ BOOST_TEST(test("description:ident", r, space));
+ BOOST_TEST(test("description: ident", r, space));
+ BOOST_TEST(!test("descriptionident", r, space));
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/spirit/repository/test/qi/keywords.cpp b/src/boost/libs/spirit/repository/test/qi/keywords.cpp
new file mode 100644
index 00000000..eb224d65
--- /dev/null
+++ b/src/boost/libs/spirit/repository/test/qi/keywords.cpp
@@ -0,0 +1,269 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2011 Thomas Bernard
+
+ 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)
+=============================================================================*/
+#include <string>
+#include <vector>
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/utility/enable_if.hpp>
+
+#include <boost/spirit/include/qi_operator.hpp>
+#include <boost/spirit/include/qi_char.hpp>
+#include <boost/spirit/include/qi_string.hpp>
+#include <boost/spirit/include/qi_numeric.hpp>
+#include <boost/spirit/include/qi_directive.hpp>
+#include <boost/spirit/include/qi_action.hpp>
+#include <boost/spirit/include/qi_nonterminal.hpp>
+#include <boost/spirit/include/support_argument.hpp>
+#include <boost/spirit/include/phoenix_core.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+#include <boost/spirit/include/phoenix_container.hpp>
+#include <boost/spirit/repository/include/qi_kwd.hpp>
+#include <boost/spirit/repository/include/qi_keywords.hpp>
+
+#include <string>
+#include <iostream>
+#include "test.hpp"
+
+struct x_attr
+{
+
+};
+
+namespace boost { namespace spirit { namespace traits
+{
+
+
+ template <>
+ struct container_value<x_attr>
+ {
+ typedef char type; // value type of container
+ };
+
+
+ template <>
+ struct push_back_container<x_attr, char>
+ {
+ static bool call(x_attr& /*c*/, char /*val*/)
+ {
+ // push back value type into container
+ return true;
+ }
+ };
+}}}
+
+int
+main()
+{
+ using spirit_test::test_attr;
+ using spirit_test::test;
+ using namespace boost::spirit;
+ using namespace boost::spirit::ascii;
+ using boost::spirit::repository::kwd;
+ using boost::spirit::repository::ikwd;
+ using boost::spirit::repository::dkwd;
+ using boost::spirit::qi::inf;
+ using boost::spirit::qi::omit;
+ using boost::spirit::qi::int_;
+ using boost::spirit::qi::lit;
+ using boost::spirit::qi::_1;
+ using boost::spirit::qi::lexeme;
+
+
+ {
+
+ // no constraints
+ boost::fusion::vector<char,char,int> data;
+ BOOST_TEST( test_attr("c=1 a=a", kwd("a")[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], data, space));
+ BOOST_TEST( boost::fusion::at_c<0>(data) == 'a' );
+ BOOST_TEST( boost::fusion::at_c<1>(data) == 0 );
+ BOOST_TEST( boost::fusion::at_c<2>(data) == 1 );
+
+ BOOST_TEST( test("a=a c=1", kwd("a")[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space));
+
+ BOOST_TEST( test("", kwd("a")[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space));
+
+ // Exact
+ BOOST_TEST(test("a=a b=b c=1", kwd("a",1)[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space));
+ BOOST_TEST(test("a=a b=c b=e c=1", kwd("a",1)[ '=' > char_] / kwd("b",2)[ '=' > char_] / kwd("c")['=' > int_], space));
+ BOOST_TEST(!test("b=c b=e c=1", kwd("a",1)[ '=' > char_] / kwd("b",2)[ '=' > char_] / kwd("c")['=' > int_], space));
+
+ // Min - Max
+ BOOST_TEST(test("a=f b=c b=e c=1", kwd("a",1,2)[ '=' > char_] / kwd("b",0,2)[ '=' > char_] / kwd("c",1,2)['=' > int_], space));
+ BOOST_TEST(!test("b=c b=e c=1", kwd("a",1,2)[ '=' > char_] / kwd("b",0,1)[ '=' > char_] / kwd("c",1,2)['=' > int_], space));
+ BOOST_TEST(test("a=g a=f b=c b=e c=1", kwd("a",1,2)[ '=' > char_] / kwd("b",0,2)[ '=' > char_] / kwd("c",1,2)['=' > int_], space));
+ BOOST_TEST(!test("a=f a=e b=c b=e a=p c=1", kwd("a",1,2)[ '=' > char_] / kwd("b",0,1)[ '=' > char_] / kwd("c",1,2)['=' > int_], space));
+
+ // Min - inf
+ BOOST_TEST(test("a=f b=c b=e c=1", kwd("a",1,inf)[ '=' > char_] / kwd("b",0,inf)[ '=' > char_] / kwd("c",1,inf)['=' > int_], space ));
+ BOOST_TEST(!test("b=c b=e c=1", kwd("a",1,inf)[ '=' > char_] / kwd("b",0,inf)[ '=' > char_] / kwd("c",1,inf)['=' > int_], space ));
+ BOOST_TEST(test("a=f a=f a=g b=c b=e c=1 a=e", kwd("a",1,inf)[ '=' > char_] / kwd("b",0,inf)[ '=' > char_] / kwd("c",1,inf)['=' > int_], space ));
+ }
+
+ { // Single keyword, empty string
+ BOOST_TEST(test(" ", kwd("aad")[char_],space));
+ // Single keyword
+ BOOST_TEST(test("aad E ", kwd("aad")[char_],space));
+ // Single no case keyword
+ BOOST_TEST(test("AaD E ", ikwd("aad")[char_],space));
+
+ }
+
+ {
+ // Vector container
+ boost::fusion::vector<std::vector<int>,std::vector<int>,std::vector<int> > data;
+ BOOST_TEST(test_attr(" a=1 b=2 b=5 c=3",kwd("a")[ '=' > int_] / kwd("b")[ '=' > int_] / kwd("c")['=' > int_] , data, space)
+ && (boost::fusion::at_c<0>(data).size()==1)
+ && (boost::fusion::at_c<0>(data)[0]==1)
+
+ &&(boost::fusion::at_c<1>(data).size()==2)
+ &&(boost::fusion::at_c<1>(data)[0]==2)
+ &&(boost::fusion::at_c<1>(data)[1]==5)
+
+ &&(boost::fusion::at_c<2>(data).size()==1)
+ &&(boost::fusion::at_c<2>(data)[0]==3)
+ );
+ }
+
+ {
+ // no_case test
+ BOOST_TEST( test("B=a c=1 a=E", no_case[kwd("a")[ "=E" ] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_]], space));
+ BOOST_TEST( test("B=a c=1 a=e", no_case[kwd("a")[ "=E" ] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_]], space));
+ BOOST_TEST( !test("B=a c=1 A=E", no_case[kwd("a")[ '=' > char_]] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space));
+ BOOST_TEST( test("b=a c=1 A=E", no_case[kwd("a")[ '=' > char_]] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space));
+ BOOST_TEST( !test("A=a c=1 a=E", kwd("a")[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space));
+ BOOST_TEST( test("A=a c=1 a=E", ikwd("a")[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space));
+ BOOST_TEST( !test("A=a C=1 a=E", ikwd("a")[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space));
+ }
+
+ {
+ // iterator restoration
+ BOOST_TEST( test("a=a c=1 ba=d", (kwd("a")[ '=' > char_] / kwd("b")[ '=' > int_] / kwd("c")['=' > int_] ) > lit("ba=") > char_, space));
+ BOOST_TEST( test("A=a c=1 ba=d", (ikwd("a")[ '=' > char_] / kwd("b")[ '=' > int_] / kwd("c")['=' > int_] ) > lit("ba=") > char_, space));
+ }
+
+ { // actions
+ namespace phx = boost::phoenix;
+
+ std::vector<int> v;
+ BOOST_TEST(test("b=2 c=4", kwd("b")['=' > int_][phx::ref(v)=_1] / kwd("c")[ '=' > int_ ],space) &&
+ v[0] == 2 );
+ }
+
+
+ {
+ // no constraints
+ boost::fusion::vector<char,char,int> data;
+ BOOST_TEST( test_attr("c,1,2=1 2,b=a", kwd( char_ >> lit(',') >> int_ )[ '=' >> char_] / kwd(int_ >> lit(',') >> char_)[ '=' >> char_] / kwd(char_ >> lit(',') >> int_ >> lit(',') >> int_)['=' >> int_], data, space));
+ BOOST_TEST( boost::fusion::at_c<0>(data) == 0 );
+ BOOST_TEST( boost::fusion::at_c<1>(data) == 'a');
+ BOOST_TEST( boost::fusion::at_c<2>(data) == 1 );
+
+ BOOST_TEST( test("2,b=a c,1,2=1", kwd( char_ >> ',' >> int_ )[ '=' >> char_] / kwd(int_ >> ',' >> char_)[ '=' >> char_] / kwd(char_ >> ',' >> int_ >> ',' >> int_)['=' >> int_], space));
+
+ BOOST_TEST( test("", kwd( char_ >> ',' >> int_ )[ '=' >> char_] / kwd(int_ >> ',' >> char_)[ '=' >> char_] / kwd(char_ >> ',' >> int_ >> ',' >> int_)['=' >> int_], space));
+
+ // Exact
+ BOOST_TEST(test("7a=a 5b=b 2c=1", kwd(int_ >> lit('a'),1)[ '=' >> char_] / kwd(int_ >> lit('b'))[ '=' >> char_] / kwd(int_ >> lit('c'))['=' >> int_], space));
+ BOOST_TEST(test("7a=a 3b=d 5b=b 2c=1", kwd(int_ >> lit('a'),1)[ '=' >> char_] / kwd(int_ >> lit('b'),2)[ '=' >> char_] / kwd(int_ >>'c')['=' >> int_], space));
+ BOOST_TEST(!test("7a=a 5b=b 2c=1", kwd(int_ >> lit('a'),1)[ '=' >> char_] / kwd(int_ >> lit('b'),2)[ '=' >> char_] / kwd(int_ >>'c')['=' >> int_], space));
+
+ // Min - Max
+ BOOST_TEST(test("6a=f 2b=c 3b=e 1c=1", kwd(int_ >> "a",1,2)[ '=' >> char_] / kwd(int_ >> "b",0,2)[ '=' >> char_] / kwd(int_ >> "c",1,2)['=' >> int_], space));
+ BOOST_TEST(!test("1b=c 6b=e 2c=1", kwd(int_ >> "a",1,2)[ '=' >> char_] / kwd(int_ >> "b",0,1)[ '=' >> char_] / kwd(int_ >> "c",1,2)['=' >> int_], space));
+ BOOST_TEST(test("4a=g 7a=f 2b=c 1b=e 4c=1", kwd(int_ >> "a",1,2)[ '=' >> char_] / kwd(int_ >> "b",0,2)[ '=' >> char_] / kwd(int_ >> "c",1,2)['=' >> int_], space));
+ BOOST_TEST(!test("1a=f a=e 2b=c 5b=e 6a=p 67c=1", kwd(int_ >> "a",1,2)[ '=' >> char_] / kwd(int_ >> "b",0,1)[ '=' >> char_] / kwd(int_ >> "c",1,2)['=' >> int_], space));
+
+ // Min - inf
+ BOOST_TEST(test("41a=f 44b=c 12b=e 45c=1", kwd(int_ >> "a",1,inf)[ '=' >> char_] / kwd(int_ >> "b",0,inf)[ '=' >> char_] / kwd(int_ >> "c",1,inf)['=' >> int_], space ));
+ BOOST_TEST(!test("31b=c 55b=e 2c=1", kwd("a",1,inf)[ '=' >> char_] / kwd("b",0,inf)[ '=' >> char_] / kwd("c",1,inf)['=' >> int_], space ));
+ BOOST_TEST(test("12a=f 45a=f 12a=g 1b=c 7b=e 12c=1 6a=e", kwd(int_ >> "a",1,inf)[ '=' >> char_] / kwd(int_ >> "b",0,inf)[ '=' >> char_] / kwd(int_ >> "c",1,inf)['=' >> int_], space ));
+
+ }
+
+ {
+
+ // Vector container
+ boost::fusion::vector<std::vector<int>,std::vector<int>,std::vector<int> > data;
+ BOOST_TEST(test_attr(" 41a=1 4b=2 12b=5 5c=3",kwd(int_ >> "a")[ '=' >> int_] / kwd(int_ >> "b")[ '=' >> int_] / kwd(int_ >> "c")['=' >> int_] , data, space)
+ && (boost::fusion::at_c<0>(data).size()==1)
+ && (boost::fusion::at_c<0>(data)[0]==1)
+
+ &&(boost::fusion::at_c<1>(data).size()==2)
+ &&(boost::fusion::at_c<1>(data)[0]==2)
+ &&(boost::fusion::at_c<1>(data)[1]==5)
+
+ &&(boost::fusion::at_c<2>(data).size()==1)
+ &&(boost::fusion::at_c<2>(data)[0]==3)
+ );
+
+
+
+ }
+
+ {
+ // no_case test
+ BOOST_TEST( test("12B=a 5c=1 1a=E", no_case[kwd(int_ >> "a")[ "=E" ] / kwd(int_ >> "b")[ '=' >> char_] / kwd(int_ >> "c")['=' >> int_]], space));
+ BOOST_TEST( test("5B=a 2c=1 5a=e", no_case[kwd(int_ >> "a")[ "=E" ] / kwd(int_ >> "b")[ '=' >> char_] / kwd(int_ >> "c")['=' >> int_]], space));
+ BOOST_TEST( !test("1B=a 8c=1 1A=E", no_case[kwd(int_ >> "a")[ '=' >> char_]] / kwd(int_ >> "b")[ '=' >> char_] / kwd(int_ >> "c")['=' >> int_], space));
+ BOOST_TEST( test("2b=a 6c=1 5A=E", no_case[kwd(int_ >> "a")[ '=' >> char_]] / kwd(int_ >> "b")[ '=' >> char_] / kwd(int_ >> "c")['=' >> int_], space));
+ BOOST_TEST( !test("1A=a 5c=1 1a=E", kwd(int_ >> "a")[ '=' >> char_] / kwd(int_ >> "b")[ '=' >> char_] / kwd(int_ >> "c")['=' >> int_], space));
+ BOOST_TEST( test("A=a 23c=1 a=E", ikwd("a")[ '=' >> char_] / kwd(int_ >> "b")[ '=' >> char_] / kwd(int_ >> "c")['=' >> int_], space));
+ BOOST_TEST( !test("A=a 21C=1 a=E", ikwd("a")[ '=' >> char_] / kwd(int_ >> "b")[ '=' >> char_] / kwd(int_ >> "c")['=' >> int_], space));
+ }
+
+ {
+ // iterator restoration
+ BOOST_TEST( test("4a=a c4=1 ba=d", (kwd(int_ >> "a")[ '=' >> char_] / kwd("b" >> int_)[ '=' >> int_] / kwd("c" >> int_ )['=' >> int_] ) >> lit("ba=") >> char_, space));
+ }
+
+ { // actions
+ namespace phx = boost::phoenix;
+
+ std::vector<int> v;
+ BOOST_TEST(test("b4=2 c1=4", kwd("b" >> int_)['=' >> int_][phx::ref(v)=_1] / kwd("c" >> int_)[ '=' >> int_ ],space) &&
+ v[0] == 2 );
+ }
+
+ {
+ // complex keyword single test
+ int result=0;
+
+ BOOST_TEST( test_attr("(a,1) = 3214", kwd( '(' >> char_ >> ',' >> int_ >> ')' )['=' >> int_], result, space) );
+ BOOST_TEST(result==3214);
+ }
+ {
+ // Mixed complex keyword loop
+ boost::fusion::vector<int,int,int> data;
+
+ BOOST_TEST( test_attr("(a,1) = 3214 b += 2 hello 10 (a,2)=31", kwd( '(' >> char_ >> ',' >> int_ >> ')' )['=' >> int_] / kwd("hello")[int_] / kwd("b")["+=" >> int_], data, space) );
+ BOOST_TEST( boost::fusion::at_c<0>(data) == 31);
+ BOOST_TEST( boost::fusion::at_c<1>(data) == 10);
+ BOOST_TEST( boost::fusion::at_c<2>(data) == 2);
+ }
+
+ // dkwd and idkwd
+ {
+ BOOST_TEST( test("a =a", dkwd("a")[ '=' > char_] , space));
+ BOOST_TEST( !test("a=a", dkwd("a")[ '=' > char_] , space));
+ BOOST_TEST(test("a =a b =b c=1", dkwd("a",1)[ '=' > char_] / dkwd("b",1,2)[ '=' > char_] / kwd("c")['=' > int_], space));
+ BOOST_TEST(!test("a=a b=b c =1", dkwd("a",1)[ '=' > char_] / dkwd("b",1,2)[ '=' > char_] / kwd("c")['=' > int_], space));
+
+ BOOST_TEST(test("a =a b =b b =d c=1", dkwd("a",1,inf)[ '=' > char_] / dkwd("b",2,inf)[ '=' > char_] / kwd("c")['=' > int_], space));
+
+ }
+
+ { // attribute customization
+
+// x_attr x;
+// test_attr("a = b c = d", kwd("a")['=' > char_] / kwd("c")['=' > char_], x);
+ }
+
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/spirit/repository/test/qi/seek.cpp b/src/boost/libs/spirit/repository/test/qi/seek.cpp
new file mode 100644
index 00000000..96183024
--- /dev/null
+++ b/src/boost/libs/spirit/repository/test/qi/seek.cpp
@@ -0,0 +1,101 @@
+/*=============================================================================
+ Copyright (c) 2011 Jamboree
+
+ 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)
+=============================================================================*/
+
+
+#include <vector>
+
+#include <boost/config/warning_disable.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#include <boost/spirit/include/qi_parse.hpp>
+#include <boost/spirit/include/qi_char.hpp>
+#include <boost/spirit/include/qi_string.hpp>
+#include <boost/spirit/include/qi_int.hpp>
+#include <boost/spirit/include/qi_sequence.hpp>
+#include <boost/spirit/include/qi_plus.hpp>
+#include <boost/spirit/include/qi_eoi.hpp>
+#include <boost/spirit/include/qi_action.hpp>
+
+#include <boost/spirit/include/phoenix_core.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+
+#include <boost/spirit/repository/include/qi_seek.hpp>
+
+#include "test.hpp"
+
+
+///////////////////////////////////////////////////////////////////////////////
+int main()
+{
+ using namespace spirit_test;
+ namespace qi = boost::spirit::qi;
+ namespace phx = boost::phoenix;
+ using boost::spirit::repository::qi::seek;
+ using boost::spirit::standard::space;
+
+ // test eoi
+ {
+ using qi::eoi;
+
+ BOOST_TEST(test("", seek[eoi]));
+ BOOST_TEST(test(" ", seek[eoi], space));
+ BOOST_TEST(test("a", seek[eoi]));
+ BOOST_TEST(test(" a", seek[eoi], space));
+ }
+
+ // test literal finding
+ {
+ using qi::int_;
+ using qi::char_;
+
+ int i = 0;
+
+ BOOST_TEST(
+ test_attr("!@#$%^&*KEY:123", seek["KEY:"] >> int_, i)
+ && i == 123
+ );
+ }
+
+ // test sequence finding
+ {
+ using qi::int_;
+ using qi::lit;
+
+ int i = 0;
+
+ BOOST_TEST(
+ test_attr("!@#$%^&* KEY : 123", seek[lit("KEY") >> ':'] >> int_, i, space)
+ && i == 123
+ );
+ }
+
+ // test attr finding
+ {
+ using qi::int_;
+
+ std::vector<int> v;
+
+ BOOST_TEST( // expect partial match
+ test_attr("a06b78c3d", +seek[int_], v, false)
+ && v[0] == 6 && v[1] == 78 && v[2] == 3
+ );
+ }
+
+ // test action
+ {
+ using phx::ref;
+
+ bool b = false;
+
+ BOOST_TEST( // expect partial match
+ test("abcdefg", seek["def"][ref(b) = true], false)
+ && b
+ );
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/repository/test/qi/subrule.cpp b/src/boost/libs/spirit/repository/test/qi/subrule.cpp
new file mode 100644
index 00000000..7eb5331f
--- /dev/null
+++ b/src/boost/libs/spirit/repository/test/qi/subrule.cpp
@@ -0,0 +1,397 @@
+/*=============================================================================
+ Copyright (c) 2001-2010 Joel de Guzman
+ Copyright (c) 2009 Francois Barel
+
+ 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)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/include/qi_operator.hpp>
+#include <boost/spirit/include/qi_char.hpp>
+#include <boost/spirit/include/qi_string.hpp>
+#include <boost/spirit/include/qi_numeric.hpp>
+#include <boost/spirit/include/qi_auxiliary.hpp>
+#include <boost/spirit/include/qi_nonterminal.hpp>
+#include <boost/spirit/include/qi_action.hpp>
+#include <boost/spirit/include/phoenix_core.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+#include <boost/spirit/include/phoenix_object.hpp>
+#include <boost/spirit/include/phoenix_bind.hpp>
+#include <boost/fusion/include/std_pair.hpp>
+
+#include <boost/spirit/repository/include/qi_subrule.hpp>
+
+#include <string>
+#include <cstring>
+#include <iostream>
+#include "test.hpp"
+
+int
+main()
+{
+ using spirit_test::test_attr;
+ using spirit_test::test;
+
+ using namespace boost::spirit::ascii;
+ using namespace boost::spirit::qi::labels;
+ using boost::spirit::qi::locals;
+ using boost::spirit::qi::rule;
+ using boost::spirit::qi::int_;
+ using boost::spirit::qi::fail;
+ using boost::spirit::qi::on_error;
+ using boost::spirit::qi::debug;
+ using boost::spirit::repository::qi::subrule;
+
+ namespace phx = boost::phoenix;
+
+
+ { // basic tests
+
+ subrule<99> entry;
+ subrule<42> a;
+ subrule<48> b;
+ subrule<16> c;
+ rule<char const*> start;
+
+ entry.name("entry");
+ a.name("a");
+ b.name("b");
+ c.name("c");
+ start.name("start");
+
+// debug(entry);
+// debug(a);
+// debug(b);
+// debug(c);
+ debug(start);
+
+ // subrules with no rule
+ BOOST_TEST(test("abcabcacb", (
+ entry = *(a | b | c)
+ , a = 'a'
+ , b = 'b'
+ , c = 'c'
+ )));
+
+ // check subrule group behaves as a parser
+ BOOST_TEST(test("xabcabcacb", 'x' >> (
+ entry = *(a | b | c)
+ , a = 'a'
+ , b = 'b'
+ , c = 'c'
+ )));
+
+ // subrules in a rule
+ start = (
+ entry = *(a | b | c)
+ , a = 'a'
+ , b = 'b'
+ , c = 'c'
+ );
+ BOOST_TEST(test("abcabcacb", start));
+
+ // subrule -> rule call
+ start = (
+ entry = (a | b) >> (start | b)
+ , a = 'a'
+ , b = 'b'
+ );
+ BOOST_TEST(test("aaaabababaaabbb", start));
+ BOOST_TEST(test("aaaabababaaabba", start, false));
+
+ // subrule recursion
+ start = (
+ entry = (a | b) >> (entry | b)
+ , a = 'a'
+ , b = 'b'
+ );
+ BOOST_TEST(test("aaaabababaaabbb", start));
+ BOOST_TEST(test("aaaabababaaabba", start, false));
+
+ // no-ops
+#if defined(BOOST_CLANG) && defined(__has_warning)
+# pragma clang diagnostic push
+# if __has_warning("-Wself-assign-overloaded")
+# pragma clang diagnostic ignored "-Wself-assign-overloaded"
+# endif
+#endif
+ a = a;
+#if defined(BOOST_CLANG) && defined(__has_warning)
+# pragma clang diagnostic pop
+#endif
+ subrule<42> aa(a);
+ }
+
+ { // basic tests w/ skipper, subrules declared const
+
+ subrule<0> const entry("entry");
+ subrule<1> const a("a");
+ subrule<2> const b("b");
+ subrule<3> const c("c");
+ rule<char const*, space_type> start("start");
+
+// debug(entry);
+// debug(a);
+// debug(b);
+// debug(c);
+ debug(start);
+
+ start = (
+ entry = *(a | b | c)
+ , a = 'a'
+ , b = 'b'
+ , c = 'c'
+ );
+ BOOST_TEST(test(" a b c a b c a c b ", start, space));
+
+ start = (
+ entry = (a | b) >> (entry | b)
+ , a = 'a'
+ , b = 'b'
+ );
+ BOOST_TEST(test(" a a a a b a b a b a a a b b b ", start, space));
+ BOOST_TEST(test(" a a a a b a b a b a a a b b a ", start, space, false));
+
+ // no-ops
+#if defined(BOOST_CLANG) && defined(__has_warning)
+# pragma clang diagnostic push
+# if __has_warning("-Wself-assign-overloaded")
+# pragma clang diagnostic ignored "-Wself-assign-overloaded"
+# endif
+#endif
+ a = a;
+#if defined(BOOST_CLANG) && defined(__has_warning)
+# pragma clang diagnostic pop
+#endif
+ subrule<1> aa(a);
+ }
+
+ { // context tests
+
+ char ch;
+ rule<char const*, char()> a;
+ subrule<0, char()> entry;
+
+ a = (entry = alpha[_val = _1])[_val = _1];
+ BOOST_TEST(test("x", a[phx::ref(ch) = _1]));
+ BOOST_TEST(ch == 'x');
+
+ a %= (entry = alpha[_val = _1]);
+ BOOST_TEST(test_attr("z", a, ch)); // attribute is given.
+ BOOST_TEST(ch == 'z');
+ }
+
+ { // auto subrules tests
+
+ char ch;
+ rule<char const*, char()> a;
+ subrule<0, char()> entry;
+
+ a = (entry %= alpha)[_val = _1];
+ BOOST_TEST(test("x", a[phx::ref(ch) = _1]));
+ BOOST_TEST(ch == 'x');
+
+ a %= (entry %= alpha);
+ BOOST_TEST(test_attr("z", a, ch)); // attribute is given.
+ BOOST_TEST(ch == 'z');
+ }
+
+ { // auto subrules tests: allow stl containers as attributes to
+ // sequences (in cases where attributes of the elements
+ // are convertible to the value_type of the container or if
+ // the element itself is an stl container with value_type
+ // that is convertible to the value_type of the attribute).
+
+ std::string s;
+ rule<char const*, std::string()> r;
+ subrule<0, std::string()> entry;
+
+ r %= (entry %= char_ >> *(',' >> char_));
+ BOOST_TEST(test("a,b,c,d,e,f", r[phx::ref(s) = _1]));
+ BOOST_TEST(s == "abcdef");
+
+ BOOST_TEST(test("abcdef", (
+ entry %= char_ >> char_ >> char_ >> char_ >> char_ >> char_
+ )[phx::ref(s) = _1]));
+ BOOST_TEST(s == "abcdef");
+ }
+
+ { // synth attribute value-init
+
+ std::string s;
+ subrule<0, char()> sr;
+ BOOST_TEST(test_attr("abcdef", +(sr = alpha[_val += _1]), s));
+ BOOST_TEST(s == "abcdef");
+ }
+
+ { // auto subrules aliasing tests
+
+ char ch;
+ rule<char const*, char()> r;
+ subrule<0, char()> a;
+ subrule<1, char()> b;
+ r %= (
+ a %= b
+ , b %= alpha
+ );
+
+ BOOST_TEST(test("x", r[phx::ref(ch) = _1]));
+ BOOST_TEST(ch == 'x');
+
+ BOOST_TEST(test_attr("z", r, ch)); // attribute is given.
+ BOOST_TEST(ch == 'z');
+ }
+
+ { // context (w/arg) tests
+
+ char ch;
+
+ // entry subrule with 1 arg
+ rule<char const*, char(int)> a;
+ subrule<1, char(int)> sr1;
+ a %= (
+ sr1 = alpha[_val = _1 + _r1]
+ )(_r1);
+ BOOST_TEST(test("x", a(phx::val(1))[phx::ref(ch) = _1]));
+ BOOST_TEST(ch == 'x' + 1);
+
+ // other subrule with 1 arg
+ subrule<0, char()> sr0;
+ a %= (
+ sr0 %= sr1(1)
+ , sr1 = alpha[_val = _1 + _r1]
+ );
+
+ // allow scalars as subrule args too
+ rule<char const*, char()> b;
+ b %= (
+ sr1 = alpha[_val = _1 + _r1]
+ )(1);
+ BOOST_TEST(test_attr("b", b, ch));
+ BOOST_TEST(ch == 'b' + 1);
+
+ // entry subrule with 2 args
+ subrule<2, char(int, int)> sr2;
+ BOOST_TEST(test_attr("a", (
+ sr2 = alpha[_val = _1 + _r1 + _r2]
+ )(1, 2), ch));
+ BOOST_TEST(ch == 'a' + 1 + 2);
+
+ // multiple subrules + args
+ BOOST_TEST(test_attr("ba", (
+ sr2 = alpha[_val = _1 + _r1 + _r2] >> sr1(3)[_val -= _1]
+ , sr1 = alpha[_val = _1 + _r1]
+ )(1, 2), ch));
+ BOOST_TEST(ch == ('b' + 1 + 2) - ('a' + 3));
+ }
+
+ { // context (w/ reference arg) tests
+
+ char ch;
+ subrule<0, void(char&)> sr; // 1 arg (reference) - direct
+ BOOST_TEST(test("x", (sr = alpha[_r1 = _1])(phx::ref(ch))));
+ BOOST_TEST(ch == 'x');
+
+ rule<char const*, void(char&)> a; // forwarded via a rule
+ a = (sr = alpha[_r1 = _1])(_r1);
+ BOOST_TEST(test("y", a(phx::ref(ch))));
+ BOOST_TEST(ch == 'y');
+ }
+
+ { // context (w/locals) tests
+
+ rule<char const*> r;
+ subrule<0, locals<char> > a; // 1 local
+ r = (
+ a = alpha[_a = _1] >> char_(_a)
+ );
+ BOOST_TEST(test("aa", r));
+ BOOST_TEST(!test("ax", r));
+ }
+
+ { // context (w/args and locals) tests
+
+ rule<char const*, void(int)> a;
+ subrule<0, void(int), locals<char> > sr; // 1 arg + 1 local
+ a = (
+ sr = alpha[_a = _1 + _r1] >> char_(_a)
+ )(_r1);
+ BOOST_TEST(test("ab", a(phx::val(1))));
+ BOOST_TEST(test("xy", a(phx::val(1))));
+ BOOST_TEST(!test("ax", a(phx::val(1))));
+ }
+
+ { // void() has unused type (void == unused_type)
+
+ std::pair<int, char> attr;
+ subrule<0, void()> sr;
+ BOOST_TEST(test_attr("123ax", int_ >> char_ >> (sr = char_), attr));
+ BOOST_TEST(attr.first == 123);
+ BOOST_TEST(attr.second == 'a');
+ }
+
+ { // test that injected attributes are ok
+
+ rule<char const*> r;
+ subrule<0, char(int)> sr;
+
+ r = (
+ sr = char_(_r1)[_val = _1]
+ )(42);
+ }
+
+ { // show that sra = srb and sra %= srb works as expected
+ subrule<0, int()> sra;
+ subrule<1, int()> srb;
+ int attr;
+
+ BOOST_TEST(test_attr("123", (sra %= int_), attr));
+ BOOST_TEST(attr == 123);
+
+ BOOST_TEST(test_attr("123", (srb %= sra, sra %= int_), attr));
+ BOOST_TEST(attr == 123);
+
+ BOOST_TEST(test_attr("123", (srb = sra, sra %= int_), attr));
+ BOOST_TEST(attr == 123);
+ }
+
+ { // std::string as container attribute with auto subrules
+
+ subrule<0, std::string()> text;
+ std::string attr;
+ BOOST_TEST(test_attr("x", (
+ text %= +(!char_(')') >> !char_('>') >> char_)
+ ), attr));
+ BOOST_TEST(attr == "x");
+ }
+
+// { // error handling
+//
+// using namespace boost::spirit::ascii;
+// using boost::phoenix::construct;
+// using boost::phoenix::bind;
+//
+// rule<char const*> r;
+// r = '(' > int_ > ',' > int_ > ')';
+//
+// on_error<fail>
+// (
+// r, std::cout
+// << phx::val("Error! Expecting: ")
+// << _4
+// << phx::val(", got: \"")
+// << construct<std::string>(_3, _2)
+// << phx::val("\"")
+// << std::endl
+// );
+//
+// BOOST_TEST(test("(123,456)", r));
+// BOOST_TEST(!test("(abc,def)", r));
+// BOOST_TEST(!test("(123,456]", r));
+// BOOST_TEST(!test("(123;456)", r));
+// BOOST_TEST(!test("[123,456]", r));
+// }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/spirit/repository/test/qi/test.hpp b/src/boost/libs/spirit/repository/test/qi/test.hpp
new file mode 100644
index 00000000..88cc7503
--- /dev/null
+++ b/src/boost/libs/spirit/repository/test/qi/test.hpp
@@ -0,0 +1,102 @@
+/*=============================================================================
+ Copyright (c) 2001-2010 Joel de Guzman
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(BOOST_SPIRIT_TEST_FEBRUARY_01_2007_0605PM)
+#define BOOST_SPIRIT_TEST_FEBRUARY_01_2007_0605PM
+
+#include <boost/spirit/include/qi_parse.hpp>
+#include <boost/spirit/include/qi_what.hpp>
+#include <boost/variant/apply_visitor.hpp>
+#include <iostream>
+
+namespace spirit_test
+{
+ template <typename Char, typename Parser>
+ inline bool test(Char const* in, Parser const& p, bool full_match = true)
+ {
+ // we don't care about the result of the "what" function.
+ // we only care that all parsers have it:
+ boost::spirit::qi::what(p);
+
+ Char const* last = in;
+ while (*last)
+ last++;
+ return boost::spirit::qi::parse(in, last, p)
+ && (!full_match || (in == last));
+ }
+
+ template <typename Char, typename Parser, typename Skipper>
+ inline bool test(Char const* in, Parser const& p
+ , Skipper const& s, bool full_match = true)
+ {
+ // we don't care about the result of the "what" function.
+ // we only care that all parsers have it:
+ boost::spirit::qi::what(p);
+
+ Char const* last = in;
+ while (*last)
+ last++;
+ return boost::spirit::qi::phrase_parse(in, last, p, s)
+ && (!full_match || (in == last));
+ }
+
+ template <typename Char, typename Parser, typename Attr>
+ inline bool test_attr(Char const* in, Parser const& p
+ , Attr& attr, bool full_match = true)
+ {
+ // we don't care about the result of the "what" function.
+ // we only care that all parsers have it:
+ boost::spirit::qi::what(p);
+
+ Char const* last = in;
+ while (*last)
+ last++;
+ return boost::spirit::qi::parse(in, last, p, attr)
+ && (!full_match || (in == last));
+ }
+
+ template <typename Char, typename Parser, typename Attr, typename Skipper>
+ inline bool test_attr(Char const* in, Parser const& p
+ , Attr& attr, Skipper const& s, bool full_match = true)
+ {
+ // we don't care about the result of the "what" function.
+ // we only care that all parsers have it:
+ boost::spirit::qi::what(p);
+
+ Char const* last = in;
+ while (*last)
+ last++;
+ return boost::spirit::qi::phrase_parse(in, last, p, s, attr)
+ && (!full_match || (in == last));
+ }
+
+ struct printer
+ {
+ typedef boost::spirit::utf8_string string;
+
+ void element(string const& tag, string const& value, int depth) const
+ {
+ for (int i = 0; i < (depth*4); ++i) // indent to depth
+ std::cout << ' ';
+
+ std::cout << "tag: " << tag;
+ if (value != "")
+ std::cout << ", value: " << value;
+ std::cout << std::endl;
+ }
+ };
+
+ inline void print_info(boost::spirit::info const& what)
+ {
+ using boost::spirit::basic_info_walker;
+
+ printer pr;
+ basic_info_walker<printer> walker(pr, what.tag, 0);
+ boost::apply_visitor(walker, what.value);
+ }
+}
+
+#endif
diff --git a/src/boost/libs/spirit/repository/test/test_headers/Jamfile b/src/boost/libs/spirit/repository/test/test_headers/Jamfile
new file mode 100644
index 00000000..0b197a68
--- /dev/null
+++ b/src/boost/libs/spirit/repository/test/test_headers/Jamfile
@@ -0,0 +1,81 @@
+# Jamfile
+#
+# Copyright (c) 2007-2008 Steven Watanabe
+# Copyright (c) 2009 Joel de Guzman
+# Copyright (c) 2009 Hartmut Kaiser
+# Copyright (c) 2009 Francois Barel
+#
+# 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
+
+import testing ;
+import path ;
+import regex ;
+import print ;
+import sequence ;
+import feature ;
+
+project boost/spirit/repository/test/test_headers
+ : requirements
+ <include>$(BOOST_ROOT)
+ <include>../../../../..
+ <c++-template-depth>300
+ ;
+
+headers =
+[
+ path.glob-tree ../../../../../boost/spirit/repository/include : *.hpp
+] ;
+
+main_headers =
+[
+ path.glob-tree ../../../../../boost/spirit/include : *.hpp : classic* phoenix1*
+] ;
+
+for local file in $(headers)
+{
+ compile test.cpp
+ : # requirements
+ <define>BOOST_SPIRIT_HEADER_NAME=$(file)
+ <dependency>$(file)
+ : # test name
+ [ regex.replace [ path.relative-to ../../../../../boost/spirit/repository $(file) ] "/" "_" ]
+ ;
+}
+
+feature.feature <generate-include-all-order> : forward reverse : incidental ;
+
+rule generate-include-all ( target : sources * : properties * )
+{
+ print.output $(target) ;
+
+ if <generate-include-all-order>reverse in $(properties)
+ {
+ sources = [ sequence.reverse $(sources) ] ;
+ }
+
+ for local file in $(sources)
+ {
+ print.text "#include <$(file:G=)>
+" : overwrite ;
+ }
+
+}
+
+make auto_all1.cpp
+ : $(headers) $(main_headers)
+ : @generate-include-all
+ ;
+
+make auto_all2.cpp
+ : $(headers) $(main_headers)
+ : @generate-include-all
+ : <generate-include-all-order>reverse
+ ;
+
+# this ought to catch non-inlined functions and other duplicate definitions
+link auto_all1.cpp auto_all2.cpp main.cpp
+ : <include>.
+ : auto_all_headers
+ ;
diff --git a/src/boost/libs/spirit/repository/test/test_headers/main.cpp b/src/boost/libs/spirit/repository/test/test_headers/main.cpp
new file mode 100644
index 00000000..99aacc62
--- /dev/null
+++ b/src/boost/libs/spirit/repository/test/test_headers/main.cpp
@@ -0,0 +1,14 @@
+// Copyright (c) 2003-2008 Matthias Christian Schabel
+// Copyright (c) 2007-2008 Steven Watanabe
+// Copyright (c) 2010 Joel de Guzman
+// Copyright (c) 2010 Hartmut Kaiser
+// Copyright (c) 2009 Francois Barel
+//
+// 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)
+
+int main()
+{
+ return 0;
+}
diff --git a/src/boost/libs/spirit/repository/test/test_headers/test.cpp b/src/boost/libs/spirit/repository/test/test_headers/test.cpp
new file mode 100644
index 00000000..c6814198
--- /dev/null
+++ b/src/boost/libs/spirit/repository/test/test_headers/test.cpp
@@ -0,0 +1,22 @@
+// Copyright (c) 2003-2008 Matthias Christian Schabel
+// Copyright (c) 2007-2008 Steven Watanabe
+// Copyright (c) 2010 Joel de Guzman
+// Copyright (c) 2010 Hartmut Kaiser
+// Copyright (c) 2009 Francois Barel
+//
+// 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)
+
+#define BOOST_SPIRIT_STRINGIZE_IMPL(x) #x
+#define BOOST_SPIRIT_STRINGIZE(x) BOOST_SPIRIT_STRINGIZE_IMPL(x)
+
+#define BOOST_SPIRIT_HEADER BOOST_SPIRIT_STRINGIZE(BOOST_SPIRIT_HEADER_NAME)
+
+#include BOOST_SPIRIT_HEADER
+#include BOOST_SPIRIT_HEADER
+
+int main()
+{
+ return 0;
+}