<|start_filename|>lab/mpllibs/metaparse/v1/always.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_ALWAYS_HPP
#define MPLLIBS_METAPARSE_V1_ALWAYS_HPP

// Copyright <NAME> (<EMAIL>)  2009 - 2010.
// 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 <mpllibs/metaparse/v1/return_.hpp>
#include <mpllibs/metaparse/v1/is_error.hpp>
#include <mpllibs/metaparse/v1/get_remaining.hpp>
#include <mpllibs/metaparse/v1/get_position.hpp>

#include <boost/mpl/apply.hpp>
#include <boost/mpl/apply_wrap.hpp>
#include <boost/mpl/eval_if.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      template <class P, class Result>
      struct always
      {
      private:
        template <class Res>
        struct apply_unchecked :
          boost::mpl::apply_wrap2<
            return_<Result>,
            typename get_remaining<Res>::type,
            typename get_position<Res>::type
          >
        {};
      public:
        typedef always type;
      
        template <class S, class Pos>
        struct apply :
          boost::mpl::eval_if<
            typename is_error<boost::mpl::apply<P, S, Pos> >::type,
            boost::mpl::apply<P, S, Pos>,
            apply_unchecked<boost::mpl::apply<P, S, Pos> >
          >
        {};
      };
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/int_.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_INT__HPP
#define MPLLIBS_METAPARSE_V1_INT__HPP

// Copyright <NAME> (<EMAIL>)  2011.
// 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 <mpllibs/metaparse/v1/digit_val.hpp>
#include <mpllibs/metaparse/v1/foldl1.hpp>

#include <boost/mpl/lambda.hpp>
#include <boost/mpl/times.hpp>
#include <boost/mpl/plus.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      typedef
        foldl1<
          digit_val,
          boost::mpl::int_<0>,
          // I need to wrap it with lambda, because int_ may be used
          // in an apply and turned into a lambda expression too early.
          boost::mpl::lambda<
            boost::mpl::plus<
              boost::mpl::times<boost::mpl::_2, boost::mpl::int_<10> >,
              boost::mpl::_1
            >
          >::type
        >
        int_;
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/impl/one_of.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_IMPL_ONE_OF_HPP
#define MPLLIBS_METAPARSE_V1_IMPL_ONE_OF_HPP

// Copyright <NAME> (<EMAIL>)  2013.
// 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 <mpllibs/metaparse/limit_one_of_size.hpp>
#include <mpllibs/metaparse/v1/error/none_of_the_expected_cases_found.hpp>
#include <mpllibs/metaparse/v1/is_error.hpp>
#include <mpllibs/metaparse/v1/fail.hpp>

#include <boost/mpl/if.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/apply_wrap.hpp>

#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/tuple/eat.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      namespace impl
      {
        #ifdef MPLLIBS_ONE_OF_BODY_PREFIX
        #  error MPLLIBS_ONE_OF_BODY_PREFIX already defined
        #endif
        #define MPLLIBS_ONE_OF_BODY_PREFIX(z, n, unused) \
          typename boost::mpl::if_< \
            boost::mpl::not_< \
              typename is_error< \
                boost::mpl::apply<BOOST_PP_CAT(P, n), S, Pos> \
              >::type \
            >, \
            BOOST_PP_CAT(P, n), \
        
        #ifdef MPLLIBS_MPLLIBS_ONE_OF
        #  error MPLLIBS_MPLLIBS_ONE_OF already defined
        #endif
        #define MPLLIBS_MPLLIBS_ONE_OF(z, n, unused) \
          template <BOOST_PP_ENUM_PARAMS(n, class P)> \
          struct BOOST_PP_CAT(one_of_, n) \
          { \
            typedef BOOST_PP_CAT(one_of_, n) type; \
            \
            template <class S, class Pos> \
            struct apply : \
              boost::mpl::apply_wrap2< \
                BOOST_PP_REPEAT(n, MPLLIBS_ONE_OF_BODY_PREFIX, ~) \
                  fail<error::none_of_the_expected_cases_found> \
                BOOST_PP_REPEAT(n, >::type BOOST_PP_TUPLE_EAT(3), ~), \
                S, \
                Pos \
              > \
            {}; \
          };
        
        BOOST_PP_REPEAT_FROM_TO(
          1,
          MPLLIBS_LIMIT_ONE_OF_SIZE,
          MPLLIBS_MPLLIBS_ONE_OF,
          ~
        )
        
        #undef MPLLIBS_MPLLIBS_ONE_OF
        #undef MPLLIBS_ONE_OF_BODY_PREFIX
      }
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/impl/accepted_keyword.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_IMPL_ACCEPTED_KEYWORD_HPP
#define MPLLIBS_METAPARSE_V1_IMPL_ACCEPTED_KEYWORD_HPP

// Copyright <NAME> (<EMAIL>)  2013.
// 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 <mpllibs/metaparse/v1/impl/accepted_keyword_tag.hpp>

#include <mpllibs/metamonad/tmp_value.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      namespace impl
      {
        struct accepted_keyword :
          metamonad::tmp_value<accepted_keyword, accepted_keyword_tag>
        {};
      }
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metamonad/v1/concat_map.hpp<|end_filename|>
#ifndef MPLLIBS_METAMONAD_V1_CONCAT_MAP_HPP
#define MPLLIBS_METAMONAD_V1_CONCAT_MAP_HPP

// Copyright <NAME> (<EMAIL>)  2013.
// 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 <mpllibs/metamonad/v1/fwd/concat_map.hpp>
#include <mpllibs/metamonad/v1/concat.hpp>
#include <mpllibs/metamonad/v1/metafunction.hpp>

#include <boost/mpl/list.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/transform_view.hpp>

namespace mpllibs
{
  namespace metamonad
  {
    namespace v1
    {
      MPLLIBS_V1_METAFUNCTION(concat_map, (L)(F))
      ((
        boost::mpl::fold<
          boost::mpl::transform_view<L, F>,
          boost::mpl::list<>,
          concat<>
        >
      ));
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/sequence.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_SEQUENCE_HPP
#define MPLLIBS_METAPARSE_SEQUENCE_HPP

// Copyright <NAME> (<EMAIL>)  2013.
// 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 <mpllibs/metaparse/v1/sequence.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    using v1::sequence;
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/parser_tag.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_PARSER_TAG_HPP
#define MPLLIBS_METAPARSE_V1_PARSER_TAG_HPP

// Copyright <NAME> (<EMAIL>)  2013.
// 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 <mpllibs/metamonad/tmp_tag.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      struct parser_tag : metamonad::tmp_tag<parser_tag> {};
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/impl/sequence_impl.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_IMPL_SEQUENCE_IMPL_HPP
#define MPLLIBS_METAPARSE_V1_IMPL_SEQUENCE_IMPL_HPP

// Copyright <NAME> (<EMAIL>)  2013.
// 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 <mpllibs/metaparse/v1/impl/apply_parser.hpp>
#include <mpllibs/metaparse/v1/return_.hpp>

#include <boost/mpl/apply_wrap.hpp>
#include <boost/mpl/deque.hpp>
#include <boost/mpl/fold.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      namespace impl
      {
        template <class Ps, class S, class Pos>
        struct sequence_impl :
          boost::mpl::fold<
            Ps,
            typename boost::mpl::apply_wrap2<
              return_<boost::mpl::deque<> >,
              S,
              Pos
            >::type,
            apply_parser
          >
        {};
      }
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/grammar.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_GRAMMAR_HPP
#define MPLLIBS_METAPARSE_V1_GRAMMAR_HPP

// Copyright <NAME> (<EMAIL>)  2012.
// 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 <mpllibs/metaparse/v1/any.hpp>
#include <mpllibs/metaparse/v1/any1.hpp>
#include <mpllibs/metaparse/v1/sequence.hpp>
#include <mpllibs/metaparse/v1/one_of.hpp>
#include <mpllibs/metaparse/v1/transform.hpp>
#include <mpllibs/metaparse/v1/lit.hpp>
#include <mpllibs/metaparse/v1/lit_c.hpp>
#include <mpllibs/metaparse/v1/token.hpp>
#include <mpllibs/metaparse/v1/keyword.hpp>
#include <mpllibs/metaparse/v1/middle_of.hpp>
#include <mpllibs/metaparse/v1/last_of.hpp>
#include <mpllibs/metaparse/v1/always.hpp>
#include <mpllibs/metaparse/v1/one_char_except_c.hpp>
#include <mpllibs/metaparse/v1/foldr1.hpp>
#include <mpllibs/metaparse/v1/foldlp.hpp>
#include <mpllibs/metaparse/v1/alphanum.hpp>
#include <mpllibs/metaparse/v1/build_parser.hpp>
#include <mpllibs/metaparse/v1/entire_input.hpp>
#include <mpllibs/metaparse/v1/string.hpp>

#include <boost/mpl/apply_wrap.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/map.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/has_key.hpp>
#include <boost/mpl/lambda.hpp>
#include <boost/mpl/push_front.hpp>
#include <boost/mpl/front.hpp>
#include <boost/mpl/back.hpp>
#include <boost/mpl/pair.hpp>
#include <boost/mpl/insert.hpp>

/*
 * The grammar
 *
 * rule_definition ::= name_token define_token expression
 * expression ::= seq_expression (or_token seq_expression)*
 * seq_expression ::= repeat_expression+
 * repeat_expression ::= name_expression (repeat_token | repeat1_token)*
 * name_expression ::= char_token | name_token | bracket_expression
 * bracket_expression ::= open_bracket_token expression close_bracket_token
 */

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      namespace grammar_util
      {
        template <char Op, class FState>
        struct repeat_apply_impl
        {
          typedef repeat_apply_impl type;
        
          template <class G>
          struct apply :
            any<typename boost::mpl::apply_wrap1<FState, G>::type>
          {};
        };

        template <class FState>
        struct repeat_apply_impl<'+', FState>
        {
          typedef repeat_apply_impl type;
        
          template <class G>
          struct apply :
            any1<typename boost::mpl::apply_wrap1<FState, G>::type>
          {};
        };

        struct build_repeat
        {
          typedef build_repeat type;
        
          template <class T, class FState>
          struct apply : repeat_apply_impl<T::type::value, FState> {};
        };
        
        struct build_sequence
        {
          typedef build_sequence type;
        
          template <class FP, class FState>
          struct apply_impl
          {
            typedef apply_impl type;
        
            template <class G>
            struct apply :
              sequence<
                typename boost::mpl::apply_wrap1<FState, G>::type,
                typename boost::mpl::apply_wrap1<FP, G>::type
              >
            {};
          };
        
          template <class FP, class FState>
          struct apply : apply_impl<FP, FState> {};
        };
        
        struct build_selection
        {
          typedef build_selection type;
        
          template <class FP, class FState>
          struct apply_impl
          {
            typedef apply_impl type;
        
            template <class G>
            struct apply :
              one_of<
                typename boost::mpl::apply_wrap1<FState, G>::type,
                typename boost::mpl::apply_wrap1<FP, G>::type
              >
            {};
          };
        
          template <class FP, class FState>
          struct apply : apply_impl<FP, FState> {};
        };
        
        template <class G, class Name>
        struct get_parser
        {
          typedef
            boost::mpl::apply_wrap1<
              typename boost::mpl::at<typename G::rules, Name>::type,
              G
            >
            p;
        
          template <class Actions>
          struct impl : transform<typename p::type, typename Actions::type> {};
        
          typedef
            typename boost::mpl::eval_if<
              typename boost::mpl::has_key<typename G::actions, Name>::type,
              impl<boost::mpl::at<typename G::actions, Name> >,
              p
            >::type
            type;
        };
        
        struct build_name
        {
          typedef build_name type;
        
          template <class Name>
          struct apply_impl
          {
            typedef apply_impl type;
        
            template <class G>
            struct apply : get_parser<G, Name> {};
          };
        
          template <class Name>
          struct apply : apply_impl<Name> {};
        };
        
        struct build_char
        {
          typedef build_char type;
        
          template <class C>
          struct apply_impl
          {
            typedef apply_impl type;
        
            template <class G>
            struct apply : lit<C> {};
          };
        
          template <class C>
          struct apply : apply_impl<C> {};
        };
        
        typedef token<lit_c<'*'> > repeat_token;
        typedef token<lit_c<'+'> > repeat1_token;
        typedef token<lit_c<'|'> > or_token;
        typedef token<lit_c<'('> > open_bracket_token;
        typedef token<lit_c<')'> > close_bracket_token;
        typedef token<keyword<string<':',':','='> > > define_token;

        typedef
          middle_of<
            lit_c<'\''>,
            one_of<
              last_of<
                lit_c<'\\'>,
                one_of<
                  always<lit_c<'n'>, boost::mpl::char_<'\n'> >,
                  always<lit_c<'r'>, boost::mpl::char_<'\r'> >,
                  always<lit_c<'t'>, boost::mpl::char_<'\t'> >,
                  lit_c<'\\'>,
                  lit_c<'\''>
                >
              >,
              one_char_except_c<'\''>
            >,
            token<lit_c<'\''> >
          >
          char_token;
        
        typedef
          token<
            foldr1<
              one_of<alphanum, lit_c<'_'> >,
              string<>,
              boost::mpl::lambda<
                boost::mpl::push_front<boost::mpl::_2, boost::mpl::_1>
              >::type
            >
          >
          name_token;
        
        struct expression;
        
        typedef
          middle_of<open_bracket_token, expression, close_bracket_token>
          bracket_expression;

        typedef
          one_of<
            transform<char_token, build_char>,
            transform<name_token, build_name>,
            bracket_expression
          >
          name_expression;

        typedef
          foldlp<
            one_of<repeat_token, repeat1_token>,
            name_expression,
            build_repeat
          >
          repeat_expression;
        
        typedef
          foldlp<repeat_expression, repeat_expression, build_sequence>
          seq_expression;
        
        struct expression :
          foldlp<
            last_of<or_token, seq_expression>,
            seq_expression,
            build_selection
          >
        {};
        
        typedef sequence<name_token, define_token, expression> rule_definition;

        typedef build_parser<entire_input<rule_definition> > parser_parser;
        
        template <class P>
        struct build_native_parser
        {
          typedef build_native_parser type;
        
          template <class G>
          struct apply
          {
            typedef P type;
          };
        };
        
        template <class S>
        struct build_parsed_parser
        {
          typedef typename boost::mpl::apply_wrap1<parser_parser, S>::type p;
          typedef typename boost::mpl::front<p>::type name;
          typedef typename boost::mpl::back<p>::type exp;
        
          struct the_parser
          {
            typedef the_parser type;
        
            template <class G>
            struct apply : boost::mpl::apply_wrap1<exp, G> {};
          };
        
          typedef boost::mpl::pair<name, the_parser> type;
        };
        
        typedef build_parser<name_token> name_parser;
        
        template <class S>
        struct rebuild : boost::mpl::apply_wrap1<name_parser, S> {};
        
        struct no_action;
        
        template <class G, class P, class F>
        struct add_rule;
        
        template <class G, class Name, class P>
        struct add_import;
        
        template <class Start, class Rules, class Actions>
        struct grammar_builder
        {
          typedef grammar_builder type;
          typedef Rules rules;
          typedef Actions actions;
        
          // Make it a parser
          template <class S, class Pos>
          struct apply :
            boost::mpl::apply_wrap2<
              typename get_parser<
                grammar_builder,
                typename rebuild<Start>::type
              >::type,
              S,
              Pos
            >
          {};
        
          template <class Name, class P>
          struct import :
            add_import<grammar_builder, typename rebuild<Name>::type, P>
          {};
        
          template <class Def, class Action = no_action>
          struct rule :
            add_rule<grammar_builder, build_parsed_parser<Def>, Action>
          {};
        };
        
        template <class Start, class Rules, class Actions, class P>
        struct add_rule<grammar_builder<Start, Rules, Actions>, P, no_action> :
          grammar_builder<
            Start,
            typename boost::mpl::insert<Rules, typename P::type>::type,
            Actions
          >
        {};
        
        template <class Start, class Rules, class Actions, class P, class F>
        struct add_rule<grammar_builder<Start, Rules, Actions>, P, F> :
          grammar_builder<
            Start,
            typename boost::mpl::insert<Rules, typename P::type>::type,
            typename boost::mpl::insert<
              Actions,
              boost::mpl::pair<
                typename P::name,
                typename boost::mpl::lambda<F>::type
              >
            >
            ::type
          >
        {};
        
        template <class Start, class Rules, class Actions, class Name, class P>
        struct add_import<grammar_builder<Start, Rules, Actions>, Name, P> :
          grammar_builder<
            Start,
            typename boost::mpl::insert<
              Rules,
              boost::mpl::pair<Name, build_native_parser<P> >
            >::type,
            Actions
          >
        {};
      }

      template <class Start = string<'S'> >
      struct grammar :
        grammar_util::grammar_builder<
          Start,
          boost::mpl::map<>,
          boost::mpl::map<>
        >
      {};
    }
  }
}

#endif


<|start_filename|>lab/mpllibs/metaparse/v1/impl/sequence.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_IMPL_SEQUENCE_HPP
#define MPLLIBS_METAPARSE_V1_IMPL_SEQUENCE_HPP

// Copyright <NAME> (<EMAIL>)  2013.
// 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 <mpllibs/metaparse/v1/impl/sequence_impl.hpp>
#include <mpllibs/metaparse/limit_sequence_size.hpp>

#include <boost/mpl/vector.hpp>

#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/cat.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      namespace impl
      {
        #ifdef MPLLIBS_SEQUENCE_CASE
        #  error MPLLIBS_SEQUENCE_CASE already defined
        #endif
        #define MPLLIBS_SEQUENCE_CASE(z, n, unused) \
          template <BOOST_PP_ENUM_PARAMS(n, class P)> \
          struct BOOST_PP_CAT(sequence, n) \
          { \
            typedef BOOST_PP_CAT(sequence, n) type; \
            \
            template <class S, class Pos> \
            struct apply : \
              sequence_impl< \
                boost::mpl::vector<BOOST_PP_ENUM_PARAMS(n, P)>, \
                S, \
                Pos \
              > \
            {}; \
          };
        
        BOOST_PP_REPEAT_FROM_TO(
          1,
          MPLLIBS_LIMIT_SEQUENCE_SIZE,
          MPLLIBS_SEQUENCE_CASE,
          ~
        )
        
        #undef MPLLIBS_SEQUENCE_CASE
      } 
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/next_line.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_NEXT_LINE_HPP
#define MPLLIBS_METAPARSE_V1_NEXT_LINE_HPP

//    Copyright <NAME> (<EMAIL>) 2011.
// 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 <mpllibs/metaparse/v1/fwd/next_line.hpp>

#include <boost/mpl/apply_wrap.hpp>
#include <boost/mpl/tag.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      template <class P, class Ch>
      struct next_line :
        boost::mpl::apply_wrap2<
          next_line_impl<typename boost::mpl::tag<typename P::type>::type>,
          typename P::type,
          typename Ch::type
        >
      {};
    }
  }
}

#endif



<|start_filename|>lab/lab5.cpp<|end_filename|>
// Copyright <NAME> (<EMAIL>)  2013.
// 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 <lab5.hpp>

#include <tmp_test.hpp>

#include <mpllibs/metaparse/string.hpp>

#include <boost/mpl/pair.hpp>
#include <boost/mpl/char.hpp>

int main()
{
  using boost::is_same;
  using boost::mpl::pair;
  using boost::mpl::char_;

  return
    (
         true

/*      && TEST_SAME(
        (pair<char_<'a'>, char_<'a'>>),
        (beginning_and_end::type::apply<MPLLIBS_STRING("a")>::type)
      )*/

/*      && TEST_SAME(
        (pair<char_<'a'>, char_<'b'>>),
        (beginning_and_end::type::apply<MPLLIBS_STRING("ab")>::type)
      )*/

/*      && TEST_SAME(
        (pair<char_<'H'>, char_<'o'>>),
        (beginning_and_end::type::apply<MPLLIBS_STRING("Hello")>::type)
      )*/
    ) ? 0 : 1;
}




<|start_filename|>lab/mpllibs/metaparse/v1/accept_when.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_ACCEPT_WHEN_HPP
#define MPLLIBS_METAPARSE_V1_ACCEPT_WHEN_HPP

// Copyright <NAME> (<EMAIL>)  2009 - 2010.
// 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 <mpllibs/metaparse/v1/get_result.hpp>
#include <mpllibs/metaparse/v1/fail.hpp>
#include <mpllibs/metaparse/v1/is_error.hpp>

#include <boost/mpl/apply.hpp>
#include <boost/mpl/apply_wrap.hpp>
#include <boost/mpl/if.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      template <class P, class Pred, class Msg>
      struct accept_when
      {
      private:
        struct unchecked
        {
          template <class S, class Pos>
          struct apply :
            boost::mpl::apply_wrap2<
              typename boost::mpl::if_<
                typename boost::mpl::apply<
                  Pred,
                  typename get_result<boost::mpl::apply<P, S, Pos> >::type
                >::type,
                P,
                fail<Msg>
              >::type,
              S,
              Pos
            >
          {};
        };
      public:
        typedef accept_when type;
        
        template <class S, class Pos>
        struct apply :
          boost::mpl::apply<
            typename boost::mpl::if_<
              is_error<boost::mpl::apply<P, S, Pos> >,
              P,
              unchecked
            >::type,
            S,
            Pos
          >
        {};
      };
    }
  }
}

#endif



<|start_filename|>lab/lab6.cpp<|end_filename|>
// Copyright <NAME> (<EMAIL>)  2013.
// 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 <lab6.hpp>

#include <regex_test.hpp>

int main()
{
  return
    (
         true
//      && all_tests(REGEX(""), "")
//      && all_tests(REGEX("a"), "a")
//      && all_tests(REGEX("abc"), "abc")
//      && all_tests(REGEX("b*"), "b*")
//      && all_tests(REGEX("ab*"), "ab*")
//      && all_tests(REGEX("b*c"), "b*c")
//      && all_tests(REGEX("ab*c"), "ab*c")
//      && all_tests(REGEX("a.*c"), "a.*c")
//      && all_tests(REGEX("a1*c"), "a1*c")
//      && all_tests(REGEX("(abc)*"), "(abc)*")
    ) ? 0 : 1;
}




<|start_filename|>lab/mpllibs/metaparse/v1/impl/is_any.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_IMPL_IS_ANY_HPP
#define MPLLIBS_METAPARSE_V1_IMPL_IS_ANY_HPP

// Copyright <NAME> (<EMAIL>)  2013.
// 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 <mpllibs/metaparse/limit_one_char_except_size.hpp>

#include <boost/mpl/equal_to.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/bool.hpp>

#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/arithmetic/dec.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      namespace impl
      {
        template <class Stub = int>
        struct is_any0
        {
          template <class C>
          struct apply : boost::mpl::true_ {};
        };

        #ifdef MPLLIBS_METAPARSE_DEFINE_IS_ANY
        #  error MPLLIBS_METAPARSE_DEFINE_IS_ANY already defined
        #endif
        #define MPLLIBS_METAPARSE_DEFINE_IS_ANY(z, n, unused) \
          template <BOOST_PP_ENUM_PARAMS(n, class T)> \
          struct BOOST_PP_CAT(is_any, n) \
          { \
            template <class C> \
            struct apply : \
              boost::mpl::eval_if< \
                typename boost::mpl::equal_to< \
                  typename C::type, \
                  typename BOOST_PP_CAT(T, BOOST_PP_DEC(n))::type \
                >::type, \
                boost::mpl::false_, \
                boost::mpl::apply_wrap1< \
                  BOOST_PP_CAT(is_any, BOOST_PP_DEC(n))< \
                    BOOST_PP_ENUM_PARAMS(BOOST_PP_DEC(n), T) \
                  >, \
                  C \
                > \
              > \
            {}; \
          };

        BOOST_PP_REPEAT_FROM_TO(
          1,
          MPLLIBS_LIMIT_ONE_CHAR_EXCEPT_SIZE,
          MPLLIBS_METAPARSE_DEFINE_IS_ANY,
          ~
        )

        #undef MPLLIBS_METAPARSE_DEFINE_IS_ANY
      }
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/middle_of.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_KEEP_MIDDLE_HPP
#define MPLLIBS_METAPARSE_KEEP_MIDDLE_HPP

// Copyright <NAME> (<EMAIL>)  2013.
// 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 <mpllibs/metaparse/v1/middle_of.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    using v1::middle_of;
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/except.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_EXCEPT_HPP
#define MPLLIBS_METAPARSE_V1_EXCEPT_HPP

// Copyright <NAME> (<EMAIL>)  2009 - 2011.
// 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 <mpllibs/metaparse/v1/is_error.hpp>
#include <mpllibs/metaparse/v1/return_.hpp>
#include <mpllibs/metaparse/v1/fail.hpp>

#include <boost/mpl/if.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/apply_wrap.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      template <class P, class Result, class ErrorMsg>
      struct except
      {
        typedef except type;
        
        template <class S, class Pos>
        struct apply :
          boost::mpl::apply_wrap2<
            typename boost::mpl::if_<
              is_error<boost::mpl::apply<P, S, Pos> >,
              return_<Result>,
              fail<ErrorMsg>
            >::type,
            S,
            Pos
          >
        {};
      };
    }
  }
}

#endif



<|start_filename|>solution/lab1.hpp<|end_filename|>
#ifndef LAB1_HPP
#define LAB1_HPP

// Copyright <NAME> (<EMAIL>)  2013.
// 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/xpressive/xpressive.hpp>

boost::xpressive::sregex

  // ""
    regex_ = boost::xpressive::sregex::compile("")

  // "a"
  , regex_a = boost::xpressive::sregex::compile("a")

  // "abc"
  , regex_abc = boost::xpressive::sregex::compile("abc")

  // "b*"
  , regex_b_ = boost::xpressive::sregex::compile("b*")

  // "ab*"
  , regex_ab_ = boost::xpressive::sregex::compile("ab*")

  // "b*c"
  , regex_b_c = boost::xpressive::sregex::compile("b*c")

  // "ab*c"
  , regex_ab_c = boost::xpressive::sregex::compile("ab*c")

  // "a.*c"
  , regex_a__c = boost::xpressive::sregex::compile("a.*c")

  // "a1*c"
  , regex_a1_c = boost::xpressive::sregex::compile("a1*c")

  // "(abc)*"
  , regex__abc__ = boost::xpressive::sregex::compile("(abc)*")

  ;

#endif



<|start_filename|>lab/mpllibs/metaparse/config.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_CONFIG_HPP
#define MPLLIBS_METAPARSE_CONFIG_HPP

// Copyright <NAME> (<EMAIL>)  2013.
// 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.hpp>

/*
 * C++11 features
 */

#if \
  !defined BOOST_NO_CXX11_VARIADIC_TEMPLATES \
  && !defined BOOST_NO_VARIADIC_TEMPLATES \
  \
  && !defined MPLLIBS_NO_VARIADIC_TEMPLATES \
  && !defined MPLLIBS_USE_VARIADIC_TEMPLATES

  #define MPLLIBS_USE_VARIADIC_TEMPLATES

#endif

#if \
  !defined BOOST_NO_CONSTEXPR \
  && !defined BOOST_NO_CXX11_CONSTEXPR \
  \
  && !defined MPLLIBS_NO_CONSTEXPR \
  && !defined MPLLIBS_USE_CONSTEXPR

  #define MPLLIBS_USE_CONSTEXPR

#endif

#ifdef MPLLIBS_USE_CONSTEXPR
#  define MPLLIBS_CONSTEXPR constexpr
#else
#  define MPLLIBS_CONSTEXPR
#endif

/*
 * Compiler workarounds
 */

#if defined __GNUC__ && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7))
#  define MPLLIBS_NO_CONSTEXPR_C_STR
#endif

/*
 * Metaparse config
 */

#if defined MPLLIBS_USE_VARIADIC_TEMPLATES && !defined MPLLIBS_VARIADIC_STRING
#  define MPLLIBS_VARIADIC_STRING
#endif

#endif



<|start_filename|>lab/regex_test.cpp<|end_filename|>
// Copyright <NAME> (<EMAIL>)  2013.
// 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 <regex_test.hpp>

#include <iostream>

namespace
{
  bool contains(const boost::xpressive::sregex& re_, const std::string& s_)
  {
    boost::xpressive::smatch w;
    return regex_search(s_, w, re_);
  }

  bool test_regex(
    const boost::xpressive::sregex& re_,
    const std::string& sre_,
    const std::string& s_
  )
  {
    using boost::xpressive::sregex;

    const bool matches = contains(re_, s_);
    const bool ref_matches = contains(sregex::compile(sre_), s_);
    const bool success = matches == ref_matches;

    std::cout
      << "  \"" << s_ << "\": " << (matches ? "matches" : "does not match")
      << (success ? "" : " <---------------- ERROR")
      << std::endl;

    return success;
  }

  bool fold_test_regex(
    const boost::xpressive::sregex& re_,
    const std::string& sre_
  )
  {
    return true;
  }

  template <class T, class... Ts>
  bool fold_test_regex(
    const boost::xpressive::sregex& re_,
    const std::string& sre_,
    T t_,
    Ts... ts_
  )
  {
    const bool r_this = test_regex(re_, sre_, t_);
    const bool r_remaining = fold_test_regex(re_, sre_, ts_...);
    return r_this && r_remaining;
  }
  
  
  template <class T, class... Ts>
  bool and_(T t_, Ts... ts_) { return t_ && and_(ts_...); }
}

bool all_tests(
  const boost::xpressive::sregex& re_,
  const std::string& sre_
)
{
  std::cout << "REGEX \"" << sre_ << "\"" << std::endl;
  return
    fold_test_regex(
        re_
      , sre_
      , ""
      , "a"
      , "ac"
      , "bac"
      , "abc"
      , "abbbbc"
      , "a1111c"
      , "abcabcabcabc"
    );
}



<|start_filename|>lab/mpllibs/metaparse/v1/any_one_of.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_ANY_ONE_OF_HPP
#define MPLLIBS_METAPARSE_V1_ANY_ONE_OF_HPP

// Copyright <NAME> (<EMAIL>)  2010.
// 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 <mpllibs/metaparse/v1/impl/one_of.hpp>
#include <mpllibs/metaparse/v1/any.hpp>

#include <boost/preprocessor/arithmetic/sub.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/tuple/eat.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      template <
        BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
          MPLLIBS_LIMIT_ONE_OF_SIZE,
          class P,
          boost::mpl::na
        )
      >
      struct any_one_of;
      
      template <>
      struct any_one_of<
        BOOST_PP_ENUM(
          MPLLIBS_LIMIT_ONE_OF_SIZE,
          boost::mpl::na BOOST_PP_TUPLE_EAT(3),
          ~
        )
      > :
        fail<error::none_of_the_expected_cases_found>
      {};

      #ifdef MPLLIBS_ANY_ONE_OF_CASE
      #  error MPLLIBS_ANY_ONE_OF_CASE already defined
      #endif
      #define MPLLIBS_ANY_ONE_OF_CASE(z, n, unused) \
        template <BOOST_PP_ENUM_PARAMS(n, class P)> \
        struct any_one_of< \
          BOOST_PP_ENUM_PARAMS(n, P) \
          BOOST_PP_COMMA_IF(n) \
          BOOST_PP_ENUM( \
            BOOST_PP_SUB(MPLLIBS_LIMIT_ONE_OF_SIZE, n), \
            boost::mpl::na BOOST_PP_TUPLE_EAT(3), \
            ~ \
          ) \
        > : any<impl::BOOST_PP_CAT(one_of_, n)<BOOST_PP_ENUM_PARAMS(n, P)> > \
        {};
      
      BOOST_PP_REPEAT_FROM_TO(
        1,
        MPLLIBS_LIMIT_ONE_OF_SIZE,
        MPLLIBS_ANY_ONE_OF_CASE,
        ~
      )
      
      #undef MPLLIBS_ANY_ONE_OF_CASE
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/any_one_of1.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_ANY_ONE_OF1_HPP
#define MPLLIBS_METAPARSE_V1_ANY_ONE_OF1_HPP

// Copyright <NAME> (<EMAIL>)  2010.
// 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 <mpllibs/metaparse/v1/impl/one_of.hpp>
#include <mpllibs/metaparse/v1/any1.hpp>

#include <boost/preprocessor/arithmetic/sub.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/tuple/eat.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      template <
        BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
          MPLLIBS_LIMIT_ONE_OF_SIZE,
          class P,
          boost::mpl::na
        )
      >
      struct any_one_of1;
      
      template <>
      struct any_one_of1<
        BOOST_PP_ENUM(
          MPLLIBS_LIMIT_ONE_OF_SIZE,
          boost::mpl::na BOOST_PP_TUPLE_EAT(3),
          ~
        )
      > :
        fail<error::none_of_the_expected_cases_found>
      {};

      #ifdef MPLLIBS_ANY_ONE_OF1_CASE
      #  error MPLLIBS_ANY_ONE_OF1_CASE already defined
      #endif
      #define MPLLIBS_ANY_ONE_OF1_CASE(z, n, unused) \
        template <BOOST_PP_ENUM_PARAMS(n, class P)> \
        struct any_one_of1< \
          BOOST_PP_ENUM_PARAMS(n, P) \
          BOOST_PP_COMMA_IF(n) \
          BOOST_PP_ENUM( \
            BOOST_PP_SUB(MPLLIBS_LIMIT_ONE_OF_SIZE, n), \
            boost::mpl::na BOOST_PP_TUPLE_EAT(3), \
            ~ \
          ) \
        > : any1<impl::BOOST_PP_CAT(one_of_, n)<BOOST_PP_ENUM_PARAMS(n, P)> > \
        {};
      
      BOOST_PP_REPEAT_FROM_TO(
        1,
        MPLLIBS_LIMIT_ONE_OF_SIZE,
        MPLLIBS_ANY_ONE_OF1_CASE,
        ~
      )
      
      #undef MPLLIBS_ANY_ONE_OF1_CASE
    }
  }
}

#endif



<|start_filename|>lab/lab2.hpp<|end_filename|>
#ifndef LAB2_HPP
#define LAB2_HPP

// Copyright <NAME> (<EMAIL>)  2013.
// 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/xpressive/xpressive.hpp>

boost::xpressive::sregex unused

  // ""
//  , regex_ = 

  // "a"
//  , regex_a =

  // "abc"
//  , regex_abc =

  // "b*"
//  , regex_b_ =

  // "ab*"
//  , regex_ab_ =

  // "b*c"
//  , regex_b_c =

  // "ab*c"
//  , regex_ab_c =

  // "a.*c"
//  , regex_a__c =

  // "a1*c"
//  , regex_a1_c =

  // "(abc)*"
//  , regex__abc__ =

  ;

#endif



<|start_filename|>lab/lab1.cpp<|end_filename|>
// Copyright <NAME> (<EMAIL>)  2013.
// 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 <lab1.hpp>

#include <regex_test.hpp>

int main()
{
  return
    (
         true
//      && all_tests(regex_, "")
//      && all_tests(regex_a, "a")
//      && all_tests(regex_abc, "abc")
//      && all_tests(regex_b_, "b*")
//      && all_tests(regex_ab_, "ab*")
//      && all_tests(regex_b_c, "b*c")
//      && all_tests(regex_ab_c, "ab*c")
//      && all_tests(regex_a__c, "a.*c")
//      && all_tests(regex_a1_c, "a1*c")
//      && all_tests(regex__abc__, "(abc)*")

    ) ? 0 : 1;
}




<|start_filename|>lab/mpllibs/metaparse/v1/digit.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_DIGIT_HPP
#define MPLLIBS_METAPARSE_V1_DIGIT_HPP

// Copyright <NAME> (<EMAIL>)  2009 - 2010.
// 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 <mpllibs/metaparse/v1/error/digit_expected.hpp>
#include <mpllibs/metaparse/v1/accept_when.hpp>
#include <mpllibs/metaparse/v1/one_char.hpp>

#include <mpllibs/metaparse/v1/util/is_digit.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      typedef
        accept_when<one_char, util::is_digit<>, error::digit_expected>
        digit;
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/string.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_STRING_HPP
#define MPLLIBS_METAPARSE_STRING_HPP

// Copyright <NAME> (<EMAIL>)  2013.
// 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 <mpllibs/metaparse/v1/string.hpp>
#include <mpllibs/metaparse/string_tag.hpp>

#ifdef MPLLIBS_STRING
#  error MPLLIBS_STRING already defined
#endif
#define MPLLIBS_STRING MPLLIBS_V1_STRING

namespace mpllibs
{
  namespace metaparse
  {
    using v1::string;
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/spaces.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_SPACES_HPP
#define MPLLIBS_METAPARSE_V1_SPACES_HPP

// Copyright <NAME> (<EMAIL>)  2009 - 2010.
// 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 <mpllibs/metaparse/v1/any1.hpp>
#include <mpllibs/metaparse/v1/space.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      typedef any1<space> spaces;
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/impl/nth_of_c_impl.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_IMPL_NTH_OF_C_IMPL_HPP
#define MPLLIBS_METAPARSE_V1_IMPL_NTH_OF_C_IMPL_HPP

// Copyright <NAME> (<EMAIL>)  2013.
// 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 <mpllibs/metaparse/v1/impl/skip_seq.hpp>

#include <boost/mpl/apply.hpp>
#include <boost/mpl/apply_wrap.hpp>
#include <boost/mpl/front.hpp>
#include <boost/mpl/pop_front.hpp>
#include <boost/mpl/fold.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      namespace impl
      {
        template <int N, class Seq>
        struct nth_of_c_impl
        {
        private:
          template <class NextResult>
          struct apply_unchecked :
            boost::mpl::apply_wrap2<
              nth_of_c_impl<
                N - 1,
                typename boost::mpl::pop_front<Seq>::type
              >,
              typename get_remaining<NextResult>::type,
              typename get_position<NextResult>::type
            >
          {};
        public:
          typedef nth_of_c_impl type;
          
          template <class S, class Pos>
          struct apply :
            boost::mpl::eval_if<
              typename is_error<
                boost::mpl::apply<typename boost::mpl::front<Seq>::type, S, Pos>
              >::type,
              boost::mpl::apply<typename boost::mpl::front<Seq>::type, S, Pos>,
              apply_unchecked<
                boost::mpl::apply<typename boost::mpl::front<Seq>::type, S, Pos>
              >
            >
          {};
        };
        
        template <class Seq>
        struct nth_of_c_impl<0, Seq>
        {
          typedef nth_of_c_impl type;
          
          template <class S, class Pos>
          struct apply :
            boost::mpl::fold<
              typename boost::mpl::pop_front<Seq>::type,
              typename boost::mpl::apply<
                typename boost::mpl::front<Seq>::type,
                S,
                Pos
              >::type,
              skip_seq
            >
          {};
        };
      }
    }
  }
}

#endif



<|start_filename|>lab/regex_test.hpp<|end_filename|>
#ifndef REGEX_TEST_HPP
#define REGEX_TEST_HPP

// Copyright <NAME> (<EMAIL>)  2013.
// 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/xpressive/xpressive.hpp>
#include <string>

bool all_tests(
  const boost::xpressive::sregex& re_,
  const std::string& sre_
);

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/is_error.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_IS_ERROR_HPP
#define MPLLIBS_METAPARSE_V1_IS_ERROR_HPP

// Copyright <NAME> (<EMAIL>)  2011.
// 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 <mpllibs/metaparse/v1/fail_tag.hpp>

#include <boost/mpl/tag.hpp>

#include <boost/type_traits/is_same.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      template <class T>
      struct is_error :
        boost::is_same<
          fail_tag,
          typename boost::mpl::tag<typename T::type>::type
        >
      {};
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/util/is_lcase_letter.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_UTIL_IS_LCASE_LETTER_HPP
#define MPLLIBS_METAPARSE_V1_UTIL_IS_LCASE_LETTER_HPP

// Copyright <NAME> (<EMAIL>)  2009 - 2010.
// 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 <mpllibs/metaparse/v1/util/in_range.hpp>

#include <boost/mpl/char.hpp>
#include <boost/mpl/vector.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      namespace util
      {
        template <class C = boost::mpl::na>
        struct is_lcase_letter :
          in_range<boost::mpl::char_<'a'>, boost::mpl::char_<'z'> >::apply<C>
        {};

        template <>
        struct is_lcase_letter<boost::mpl::na>
        {
          typedef is_lcase_letter type;

          template <class C = boost::mpl::na>
          struct apply : is_lcase_letter<C> {};
        };
      }
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/lit.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_LIT_HPP
#define MPLLIBS_METAPARSE_V1_LIT_HPP

// Copyright <NAME> (<EMAIL>)  2009 - 2010.
// 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 <mpllibs/metaparse/v1/error/literal_expected.hpp>
#include <mpllibs/metaparse/v1/accept_when.hpp>
#include <mpllibs/metaparse/v1/one_char.hpp>

#include <boost/mpl/equal_to.hpp>
#include <boost/mpl/lambda.hpp>
#include <boost/mpl/push_back.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      template <class C>
      struct lit :
        accept_when<
          one_char,
          typename boost::mpl::lambda<
            boost::mpl::equal_to<boost::mpl::_1, C>
          >::type,
          error::literal_expected<C>
        >
      {};
    }
  }
}

#endif




<|start_filename|>Makefile<|end_filename|>
# Copyright <NAME> (<EMAIL>)  2013.
# 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)

help :
	@echo "Supported targets:"
	@echo "  doc -> html README.md"
	@echo "  README.md"
	@echo "  html"
	@echo "  test"
	@echo "  clean"

doc : html README.md

README.md : doc/README.md
	doc/tools/gen_toc -i $< -o $@ -t github
.PHONY: README.md

html :
	$(MAKE) -C doc html
.PHONY: html


clean :
	$(MAKE) -C doc clean
	$(MAKE) -C lab clean

test :
	$(MAKE) -C lab test




<|start_filename|>lab/lab3.cpp<|end_filename|>
// Copyright <NAME> (<EMAIL>)  2013.
// 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 <lab3.hpp>

#include <regex_test.hpp>

#include <boost/mpl/char.hpp>

int main()
{
  using namespace boost;

  return
    (
         true

//      && all_tests(r_empty::type::run(), "")

/*      && all_tests(
        r_concat<
          r_empty,
          r_char<mpl::char_<'a'>>
        >::type::run(),
        "a"
      )*/

/*      && all_tests(
        r_concat<
          r_concat<
            r_concat<
              r_empty,
              r_char<mpl::char_<'a'>>
            >,
            r_char<mpl::char_<'b'>>
          >,
          r_char<mpl::char_<'c'>>
        >::type::run(),
        "abc"
      )*/

/*      && all_tests(
        r_concat<
          r_empty,
          r_star<
            r_char<mpl::char_<'b'>>
          >
        >::type::run(),
        "b*"
      )*/

/*      && all_tests(
        r_concat<
          r_concat<
            r_empty,
            r_char<mpl::char_<'a'>>
          >,
          r_star<
            r_char<mpl::char_<'b'>>
          >
        >::type::run(),
        "ab*"
      )*/

/*      && all_tests(
        r_concat<
          r_concat<
            r_empty,
            r_star<
              r_char<mpl::char_<'b'>>
            >
          >,
          r_char<mpl::char_<'c'>>
        >::type::run(),
        "b*c"
      )*/

/*      && all_tests(
        r_concat<
          r_concat<
            r_concat<
              r_empty,
              r_char<mpl::char_<'a'>>
            >,
            r_star<
              r_char<mpl::char_<'b'>>
            >
          >,
          r_char<mpl::char_<'c'>>
        >::type::run(),
        "ab*c"
      )*/

/*      && all_tests(
        r_concat<
          r_concat<
            r_concat<
              r_empty,
              r_char<mpl::char_<'a'>>
            >,
            r_star<
              r_dot
            >
          >,
          r_char<mpl::char_<'c'>>
        >::type::run(),
        "a.*c"
      )*/

/*      && all_tests(
        r_concat<
          r_concat<
            r_concat<
              r_empty,
              r_char<mpl::char_<'a'>>
            >,
            r_star<
              r_char<mpl::char_<'1'>>
            >
          >,
          r_char<mpl::char_<'c'>>
        >::type::run(),
        "a1*c"
      )*/

/*      && all_tests(
        r_concat<
          r_empty,
          r_star<
            r_concat<
              r_concat<
                r_concat<
                  r_empty,
                  r_char<mpl::char_<'a'>>
                >,
                r_char<mpl::char_<'b'>>
              >,
              r_char<mpl::char_<'c'>>
            >
          >
        >::type::run(),
        "(abc)*"
      )*/

    ) ? 0 : 1;
}




<|start_filename|>lab/mpllibs/metaparse/v1/impl/update_c.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_IMPL_UPDATE_C_HPP
#define MPLLIBS_METAPARSE_V1_IMPL_UPDATE_C_HPP

// Copyright <NAME> (<EMAIL>)  2013.
// 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 <mpllibs/metaparse/config.hpp>
#include <mpllibs/metaparse/v1/fwd/string.hpp>
#include <mpllibs/metaparse/v1/impl/split_at_c.hpp>
#include <mpllibs/metaparse/v1/impl/concat.hpp>

#include <boost/preprocessor/arithmetic/dec.hpp>
#include <boost/preprocessor/arithmetic/inc.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      namespace impl
      {
        template <class S, int N, char C>
        struct update_c;

#ifndef MPLLIBS_VARIADIC_STRING
        #ifdef MPLLIBS_ARGN
        #  error MPLLIBS_ARGN already defined
        #endif
        #define MPLLIBS_ARGN(z, n, unused) , BOOST_PP_CAT(C, n)

        #ifdef MPLLIBS_UPDATE
        #  error MPLLIBS_UPDATE already defined
        #endif
        #define MPLLIBS_UPDATE(z, n, unused) \
          template < \
            BOOST_PP_ENUM_PARAMS(MPLLIBS_LIMIT_STRING_SIZE, int C), \
            char Ch \
          > \
          struct update_c< \
            string<BOOST_PP_ENUM_PARAMS(MPLLIBS_LIMIT_STRING_SIZE, C)>, \
            n, \
            Ch \
          > : \
            string< \
              BOOST_PP_ENUM_PARAMS(n, C) BOOST_PP_COMMA_IF(n) \
              Ch \
              BOOST_PP_REPEAT_FROM_TO( \
                BOOST_PP_INC(n), \
                BOOST_PP_DEC(MPLLIBS_LIMIT_STRING_SIZE), \
                MPLLIBS_ARGN, \
                ~ \
              ) \
            > \
          {};

        BOOST_PP_REPEAT(MPLLIBS_LIMIT_STRING_SIZE, MPLLIBS_UPDATE, ~)

        #undef MPLLIBS_UPDATE
        #undef MPLLIBS_ARGN
#else
        template <class S, int N, char C>
        struct update_c :
          concat<
            typename split_at_c<N, S>::type::first,
            typename
              update_c<typename split_at_c<N, S>::type::second, 0, C>::type
          >
        {};
  
        template <char... Cs, char C, char NewChar>
        struct update_c<string<C, Cs...>, 0, NewChar> :
          string<NewChar, Cs...>
        {};
#endif
      }
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/empty.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_EMPTY_HPP
#define MPLLIBS_METAPARSE_V1_EMPTY_HPP

// Copyright <NAME> (<EMAIL>)  2010 - 2011.
// 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 <mpllibs/metaparse/v1/error/end_of_input_expected.hpp>
#include <mpllibs/metaparse/v1/fail.hpp>
#include <mpllibs/metaparse/v1/return_.hpp>
#include <mpllibs/metaparse/v1/define_error.hpp>

#include <boost/mpl/empty.hpp>
#include <boost/mpl/apply_wrap.hpp>
#include <boost/mpl/if.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      template <class Result>
      struct empty
      {
        typedef empty type;
        
        template <class S, class Pos>
        struct apply :
          boost::mpl::apply_wrap2<
            typename boost::mpl::if_<
              boost::mpl::empty<S>,
              return_<Result>,
              fail<error::end_of_input_expected>
            >::type,
            S,
            Pos
          >
        {};
      };
    }
  }
}

#endif



<|start_filename|>solution/lab6.hpp<|end_filename|>
#ifndef LAB6_HPP
#define LAB6_HPP

// Copyright <NAME> (<EMAIL>)  2013.
// 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 <lab3.hpp>

#include <mpllibs/metaparse/always.hpp>
#include <mpllibs/metaparse/transform.hpp>
#include <mpllibs/metaparse/middle_of.hpp>
#include <mpllibs/metaparse/one_of.hpp>
#include <mpllibs/metaparse/lit_c.hpp>
#include <mpllibs/metaparse/letter.hpp>
#include <mpllibs/metaparse/digit.hpp>
#include <mpllibs/metaparse/foldl.hpp>
#include <mpllibs/metaparse/build_parser.hpp>
#include <mpllibs/metaparse/string.hpp>
#include <mpllibs/metaparse/sequence.hpp>
#include <mpllibs/metaparse/return_.hpp>

#include <boost/xpressive/xpressive.hpp>

#include <boost/mpl/front.hpp>
#include <boost/mpl/back.hpp>
#include <boost/mpl/char.hpp>

/*
 * Semantic actions
 */

struct build_char_
{
  typedef build_char_ type;

  template <class C>
  struct apply : r_char<C> {};
};

template <class RegExp, char Repeat>
struct build_unary_item_impl;

template <class RegExp>
struct build_unary_item_impl<RegExp, '*'> : r_star<RegExp> {};

template <class RegExp>
struct build_unary_item_impl<RegExp, 'x'> : RegExp {};

struct build_unary_item
{
  typedef build_unary_item type;

  template <class S>
  struct apply :
    build_unary_item_impl<
      boost::mpl::front<S>,
      boost::mpl::back<S>::type::value
    >
  {};
};

struct build_reg_exp
{
  typedef build_reg_exp type;

  template <class NewExp, class OldExp>
  struct apply : r_concat<OldExp, NewExp> {};
};

/*
 * The parser
 *
 * reg_exp ::= unary_item*
 * unary_item ::= item '*'?
 * item ::= any | bracket_exp | char_
 * any ::= '.'
 * bracket_exp ::= '(' reg_exp ')'
 * char_ ::= number | letter
 * number ::= '0'..'9'
 * letter ::= 'a'..'z' | 'A'..'Z'
 * 
 */

struct reg_exp;

typedef mpllibs::metaparse::always<mpllibs::metaparse::lit_c<'.'>, r_dot> any;

typedef
  mpllibs::metaparse::transform<
    mpllibs::metaparse::one_of<
      mpllibs::metaparse::letter,
      mpllibs::metaparse::digit
    >,
    build_char_
  >
  char_;

typedef
  mpllibs::metaparse::middle_of<
    mpllibs::metaparse::lit_c<'('>,
    reg_exp,
    mpllibs::metaparse::lit_c<')'>
  >
  bracket_exp;

typedef mpllibs::metaparse::one_of<any, bracket_exp, char_> item;

typedef
  mpllibs::metaparse::transform<
    mpllibs::metaparse::sequence<
      item,
      mpllibs::metaparse::one_of<
        mpllibs::metaparse::lit_c<'*'>,
        mpllibs::metaparse::return_<boost::mpl::char_<'x'>>
      >
    >,
    build_unary_item
  >
  unary_item;

struct reg_exp :
  mpllibs::metaparse::foldl<unary_item, r_empty, build_reg_exp>
{};

typedef mpllibs::metaparse::build_parser<reg_exp> regex_parser;

#ifdef REGEX
  #error REGEX already defined
#endif
#define REGEX(s) (regex_parser::apply<MPLLIBS_STRING((s))>::type::run())

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/look_ahead.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_LOOK_AHEAD_HPP
#define MPLLIBS_METAPARSE_V1_LOOK_AHEAD_HPP

// Copyright <NAME> (<EMAIL>)   2011.
// 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 <mpllibs/metaparse/v1/is_error.hpp>
#include <mpllibs/metaparse/v1/return_.hpp>
#include <mpllibs/metaparse/v1/get_result.hpp>

#include <boost/mpl/apply.hpp>
#include <boost/mpl/apply_wrap.hpp>
#include <boost/mpl/eval_if.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      template <class P>
      struct look_ahead
      {
        typedef look_ahead type;
        
        template <class S, class Pos>
        struct apply :
          boost::mpl::eval_if<
            typename is_error<boost::mpl::apply<P, S, Pos> >::type,
            boost::mpl::apply<P, S, Pos>,
            boost::mpl::apply_wrap2<
              return_<get_result<boost::mpl::apply<P, S, Pos> > >,
              S,
              Pos
            >
          >
        {};
      };
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/util/is_ucase_letter.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_UTIL_IS_UCASE_LETTER_HPP
#define MPLLIBS_METAPARSE_V1_UTIL_IS_UCASE_LETTER_HPP

// Copyright <NAME> (<EMAIL>)  2009 - 2010.
// 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 <mpllibs/metaparse/v1/util/in_range.hpp>

#include <boost/mpl/char.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      namespace util
      {
        template <class C = boost::mpl::na>
        struct is_ucase_letter :
          in_range<boost::mpl::char_<'A'>, boost::mpl::char_<'Z'> >::apply<C>
        {};

        template <>
        struct is_ucase_letter<boost::mpl::na>
        {
          typedef is_ucase_letter type;

          template <class C = boost::mpl::na>
          struct apply : is_ucase_letter<C> {};
        };
      }
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/one_char.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_ONE_CHAR_HPP
#define MPLLIBS_METAPARSE_V1_ONE_CHAR_HPP

// Copyright <NAME> (<EMAIL>)  2009 - 2011.
// 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 <mpllibs/metaparse/v1/error/unexpected_end_of_input.hpp>
#include <mpllibs/metaparse/v1/next_char.hpp>
#include <mpllibs/metaparse/v1/next_line.hpp>
#include <mpllibs/metaparse/v1/return_.hpp>
#include <mpllibs/metaparse/v1/fail.hpp>
#include <mpllibs/metaparse/v1/get_prev_char.hpp>

#include <boost/mpl/empty.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/front.hpp>
#include <boost/mpl/pop_front.hpp>
#include <boost/mpl/apply_wrap.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/equal_to.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/char.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      struct one_char
      {
      private:
        template <class C, class Pos>
        struct next_pos :
          boost::mpl::eval_if<
            typename boost::mpl::or_<
              typename boost::mpl::equal_to<
                boost::mpl::char_<'\r'>,
                typename C::type
              >::type,
              typename boost::mpl::and_<
                typename boost::mpl::equal_to<
                  boost::mpl::char_<'\n'>,
                  typename C::type
                >::type,
                typename boost::mpl::not_<
                  typename boost::mpl::equal_to<
                    boost::mpl::char_<'\r'>,
                    typename get_prev_char<Pos>::type
                  >::type
                >
              >::type
            >::type,
            next_line<Pos, C>,
            next_char<Pos, C>
          >
        {};
      public:
        typedef one_char type;
        
        template <class S, class Pos>
        struct apply :
          boost::mpl::eval_if<
            typename boost::mpl::empty<S>::type,
            boost::mpl::apply_wrap2<
              fail<error::unexpected_end_of_input>,
              S,
              Pos
            >,
            boost::mpl::apply_wrap2<
              return_<boost::mpl::front<S> >,
              boost::mpl::pop_front<S>,
              next_pos<boost::mpl::front<S>, Pos>
            >
          >
        {};
      };
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/last_of.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_LAST_OF_HPP
#define MPLLIBS_METAPARSE_V1_LAST_OF_HPP

// Copyright <NAME> (<EMAIL>)  2009 - 2010.
// 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 <mpllibs/metaparse/v1/nth_of.hpp>

#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/arithmetic/sub.hpp>
#include <boost/preprocessor/tuple/eat.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      template <
        BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
          MPLLIBS_LIMIT_SEQUENCE_SIZE,
          class P,
          boost::mpl::na
        )
      >
      struct last_of;

      #ifdef MPLLIBS_LAST_OF_N
      #  error MPLLIBS_LAST_OF_N already defined
      #endif
      #define MPLLIBS_LAST_OF_N(z, n, unused) \
        template <BOOST_PP_ENUM_PARAMS(n, class P)> \
        struct last_of< \
          BOOST_PP_ENUM_PARAMS(n, P) \
          BOOST_PP_COMMA_IF(n) \
          BOOST_PP_ENUM( \
            BOOST_PP_SUB(MPLLIBS_LIMIT_SEQUENCE_SIZE, n), \
            boost::mpl::na BOOST_PP_TUPLE_EAT(3), \
            ~ \
          ) \
        > : \
          impl::BOOST_PP_CAT(nth_of_c, n)< \
            n - 1 BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, P) \
          > \
        {};
      
      BOOST_PP_REPEAT(MPLLIBS_LIMIT_SEQUENCE_SIZE, MPLLIBS_LAST_OF_N, ~)
      
      #undef MPLLIBS_LAST_OF_N
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/safe_printf/v1/fwd/printf.hpp<|end_filename|>
#ifndef MPLLIBS_SAFE_PRINTF_V1_FWD_PRINTF_HPP
#define MPLLIBS_SAFE_PRINTF_V1_FWD_PRINTF_HPP

// Copyright <NAME> (<EMAIL>)  2013.
// 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 <mpllibs/safe_printf/printf_max_argument.hpp>

#include <boost/preprocessor/comma_if.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>

#include <cstdio>

namespace mpllibs
{
  namespace safe_printf
  {
    namespace v1
    {
      #ifdef MPLLIBS_PRINTF_TEMPLATE
      #  error MPLLIBS_PRINTF_TEMPLATE already defined
      #endif
      #define MPLLIBS_PRINTF_TEMPLATE(n) \
        template < \
          class FormatString \
          BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, class T) \
        >
 
      #ifdef MPLLIBS_PRINTF
      #  error MPLLIBS_PRINTF already defined
      #endif
      #define MPLLIBS_PRINTF(z, n, unused) \
        MPLLIBS_PRINTF_TEMPLATE(n) \
        int printf(BOOST_PP_ENUM_BINARY_PARAMS(n, T, t)); \
        \
        MPLLIBS_PRINTF_TEMPLATE(n) \
        int fprintf( \
          FILE* stream BOOST_PP_COMMA_IF(n) \
          BOOST_PP_ENUM_BINARY_PARAMS(n, T, t) \
        ); \
        \
        MPLLIBS_PRINTF_TEMPLATE(n) \
        int sprintf( \
          char* s BOOST_PP_COMMA_IF(n) \
          BOOST_PP_ENUM_BINARY_PARAMS(n, T, t) \
        );
  
      BOOST_PP_REPEAT(MPLLIBS_PRINTF_MAX_ARGUMENT, MPLLIBS_PRINTF, ~)
  
      #undef MPLLIBS_PRINTF
      #undef MPLLIBS_PRINTF_TEMPLATE
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/always_c.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_ALWAYS_C_HPP
#define MPLLIBS_METAPARSE_V1_ALWAYS_C_HPP

// Copyright <NAME> (<EMAIL>)  2013.
// 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 <mpllibs/metaparse/v1/always.hpp>
#include <mpllibs/metaparse/v1/lit_c.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      template <char C, class Result>
      struct always_c : always<lit_c<C>, Result> {};
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/impl/size.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_IMPL_SIZE_HPP
#define MPLLIBS_METAPARSE_V1_IMPL_SIZE_HPP

// Copyright <NAME> (<EMAIL>)  2013.
// 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 <mpllibs/metaparse/config.hpp>
#include <mpllibs/metaparse/v1/fwd/string.hpp>

#include <boost/mpl/int.hpp>

#include <boost/preprocessor/arithmetic/sub.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/tuple/eat.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      namespace impl
      {
        template <class S>
        struct size;

#ifdef MPLLIBS_VARIADIC_STRING
        template <char... Cs>
        struct size<string<Cs...>> : boost::mpl::int_<sizeof...(Cs)> {};
#else
        #ifdef MPLLIBS_STRING_CASE
        #  error MPLLIBS_STRING_CASE
        #endif
        #define MPLLIBS_STRING_CASE(z, n, unused) \
          template <BOOST_PP_ENUM_PARAMS(n, int C)> \
          struct \
            size< \
              string< \
                BOOST_PP_ENUM_PARAMS(n, C) BOOST_PP_COMMA_IF(n) \
                BOOST_PP_ENUM( \
                  BOOST_PP_SUB(MPLLIBS_LIMIT_STRING_SIZE, n), \
                  MPLLIBS_NO_CHAR BOOST_PP_TUPLE_EAT(3), \
                  ~ \
                ) \
              > \
            > : \
            boost::mpl::int_<n> \
          {};
  
        BOOST_PP_REPEAT(MPLLIBS_LIMIT_STRING_SIZE, MPLLIBS_STRING_CASE, ~)
  
        #undef MPLLIBS_STRING_CASE
#endif
      }
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/impl/iterate_impl_unchecked.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_IMPL_ITERATE_IMPL_UNCHECKED_HPP
#define MPLLIBS_METAPARSE_V1_IMPL_ITERATE_IMPL_UNCHECKED_HPP

// Copyright <NAME> (<EMAIL>)  2013.
// 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 <mpllibs/metaparse/v1/impl/fwd/iterate_impl.hpp>
#include <mpllibs/metaparse/v1/get_result.hpp>
#include <mpllibs/metaparse/v1/get_remaining.hpp>
#include <mpllibs/metaparse/v1/get_position.hpp>

#include <boost/mpl/apply.hpp>
#include <boost/mpl/apply_wrap.hpp>
#include <boost/mpl/push_back.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      namespace impl
      {
        template <int N, class P, class Accum, class S, class Pos>
        struct iterate_impl_unchecked :
          boost::mpl::apply_wrap2<
            iterate_impl<
              N - 1,
              P,
              typename boost::mpl::push_back<
                Accum,
                typename get_result<boost::mpl::apply<P, S, Pos> >::type
              >::type
            >,
            typename get_remaining<boost::mpl::apply<P, S, Pos> >::type,
            typename get_position<boost::mpl::apply<P, S, Pos> >::type
          >
        {};
      }
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/one_of.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_ONE_OF_HPP
#define MPLLIBS_METAPARSE_V1_ONE_OF_HPP

// Copyright <NAME> (<EMAIL>)  2009 - 2010.
// 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 <mpllibs/metaparse/v1/impl/one_of.hpp>
#include <mpllibs/metaparse/v1/error/none_of_the_expected_cases_found.hpp>
#include <mpllibs/metaparse/v1/fail.hpp>
#include <mpllibs/metaparse/limit_one_of_size.hpp>

#include <boost/preprocessor/arithmetic/sub.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/tuple/eat.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      template <
        BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
          MPLLIBS_LIMIT_ONE_OF_SIZE,
          class P,
          boost::mpl::na
        )
      >
      struct one_of;

      template <>
      struct one_of<
        BOOST_PP_ENUM(
          MPLLIBS_LIMIT_ONE_OF_SIZE,
          boost::mpl::na BOOST_PP_TUPLE_EAT(3),
          ~
        )
      > :
        fail<error::none_of_the_expected_cases_found>
      {};
      
      #ifdef MPLLIBS_ONE_OF_CASE
      #  error MPLLIBS_ONE_OF_CASE already defined
      #endif
      #define MPLLIBS_ONE_OF_CASE(z, n, unused) \
        template <BOOST_PP_ENUM_PARAMS(n, class P)> \
        struct one_of< \
          BOOST_PP_ENUM_PARAMS(n, P) \
          BOOST_PP_COMMA_IF(n) \
          BOOST_PP_ENUM( \
            BOOST_PP_SUB(MPLLIBS_LIMIT_ONE_OF_SIZE, n), \
            boost::mpl::na BOOST_PP_TUPLE_EAT(3), \
            ~ \
          ) \
        > : impl::BOOST_PP_CAT(one_of_, n)<BOOST_PP_ENUM_PARAMS(n, P)> \
        {};
      
      BOOST_PP_REPEAT_FROM_TO(
        1,
        MPLLIBS_LIMIT_ONE_OF_SIZE,
        MPLLIBS_ONE_OF_CASE,
        ~
      )
      
      #undef MPLLIBS_ONE_OF_CASE
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/foldrp.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_FOLDRP_HPP
#define MPLLIBS_METAPARSE_V1_FOLDRP_HPP

// Copyright <NAME> (<EMAIL>)  2012.
// 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 <mpllibs/metaparse/v1/return_.hpp>
#include <mpllibs/metaparse/v1/is_error.hpp>
#include <mpllibs/metaparse/v1/get_position.hpp>
#include <mpllibs/metaparse/v1/get_result.hpp>
#include <mpllibs/metaparse/v1/get_remaining.hpp>

#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/apply_wrap.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      template <class P, class StateP, class BackwardOp>
      struct foldrp
      {
      private:
        template <class Res, class Rem>
        struct apply_unchecked1 :
          boost::mpl::apply_wrap2<
            return_<
              typename boost::mpl::apply<
                BackwardOp,
                typename get_result<Res>::type,
                typename get_result<Rem>::type
              >::type
            >,
            typename get_remaining<Rem>::type,
            typename get_position<Rem>::type
          >
        {};

        template <class Res>
        struct apply_unchecked
        {
        private:
          typedef
            // I need to use apply_wrap, and not apply, because apply would
            // build a metafunction class from foldrp<P, StateP, BackwardOp>
            // when BackwardOp is a lambda expression.
            boost::mpl::apply_wrap2<
              foldrp,
              typename get_remaining<Res>::type,
              typename get_position<Res>::type
            >
            parsed_remaining;
        public:
          typedef
            typename boost::mpl::eval_if<
              typename is_error<parsed_remaining>::type,
              parsed_remaining,
              apply_unchecked1<Res, parsed_remaining>
            >::type
            type;
        };
      public:
        typedef foldrp type;
      
        template <class S, class Pos>
        struct apply :
          boost::mpl::eval_if<
            typename is_error<boost::mpl::apply<P, S, Pos> >::type,
            boost::mpl::apply<StateP, S, Pos>,
            apply_unchecked<boost::mpl::apply<P, S, Pos> >
          >
        {};
      };
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/transform.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_TRANSFORM_HPP
#define MPLLIBS_METAPARSE_V1_TRANSFORM_HPP

// Copyright <NAME> (<EMAIL>)  2009 - 2010.
// 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 <mpllibs/metaparse/v1/return_.hpp>
#include <mpllibs/metaparse/v1/get_result.hpp>
#include <mpllibs/metaparse/v1/get_remaining.hpp>
#include <mpllibs/metaparse/v1/get_position.hpp>
#include <mpllibs/metaparse/v1/unless_error.hpp>

#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/apply_wrap.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      template <class P, class T>
      struct transform
      {
      private:
        template <class R>
        struct apply_transformation_function :
          boost::mpl::apply<T, typename R::type>
        {};
        
      public:
        typedef transform type;
        
        template <class S, class Pos>
        struct apply :
          unless_error<
            boost::mpl::apply<P, S, Pos>,
            boost::mpl::apply_wrap2<
              return_<
                apply_transformation_function<
                  get_result<boost::mpl::apply<P, S, Pos> >
                >
              >,
              get_remaining<boost::mpl::apply<P, S, Pos> >,
              get_position<boost::mpl::apply<P, S, Pos> >
            >
          >
        {};
      };
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/return_.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_RETURN__HPP
#define MPLLIBS_METAPARSE_V1_RETURN__HPP

// Copyright <NAME> (<EMAIL>)  2009 - 2010.
// 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 <mpllibs/metaparse/v1/accept_tag.hpp>
#include <mpllibs/metaparse/v1/get_result.hpp>

#include <mpllibs/metamonad/tmp_tag.hpp>

#include <iostream>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      template <class C>
      struct return_
      {
        typedef return_ type;
        
        template <class S, class Pos>
        struct apply
        {
          typedef accept_tag tag;
          typedef apply type;
  
          typedef C result;
          typedef S remaining;
          typedef Pos source_position;
        };
      };
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/util/is_letter.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_UTIL_IS_LETTER_HPP
#define MPLLIBS_METAPARSE_V1_UTIL_IS_LETTER_HPP

// Copyright <NAME> (<EMAIL>)  2009 - 2010.
// 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 <mpllibs/metaparse/v1/util/is_ucase_letter.hpp>
#include <mpllibs/metaparse/v1/util/is_lcase_letter.hpp>

#include <boost/mpl/or.hpp>
#include <boost/mpl/apply.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      namespace util
      {
        template <class C = boost::mpl::na>
        struct is_letter :
          boost::mpl::or_<
            typename is_lcase_letter<C>::type,
            typename is_ucase_letter<C>::type
          >
        {};

        template <>
        struct is_letter<boost::mpl::na>
        {
          typedef is_letter type;
          
          template <class C = boost::mpl::na>
          struct apply : is_letter<C> {};
        };
      }
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/foldlp.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_FOLDLP_HPP
#define MPLLIBS_METAPARSE_V1_FOLDLP_HPP

// Copyright <NAME> (<EMAIL>)  2012.
// 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 <mpllibs/metaparse/v1/foldl.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      template <class P, class StateP, class ForwardOp>
      class foldlp
      {
      private:
        template <class Res>
        struct apply_unchecked :
          boost::mpl::apply_wrap2<
            foldl<P, typename get_result<Res>::type, ForwardOp>,
            typename get_remaining<Res>::type,
            typename get_position<Res>::type
          >
        {};
      public:
        typedef foldlp type;

        template <class S, class Pos>
        struct apply :
          boost::mpl::eval_if<
            typename is_error<boost::mpl::apply<StateP, S, Pos> >::type,
            boost::mpl::apply<StateP, S, Pos>,
            apply_unchecked<boost::mpl::apply<StateP, S, Pos> >
          >
        {};
      };
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/first_of.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_FIRST_OF_HPP
#define MPLLIBS_METAPARSE_V1_FIRST_OF_HPP

// Copyright <NAME> (<EMAIL>)  2009 - 2010.
// 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 <mpllibs/metaparse/v1/nth_of.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      template <
        BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
          MPLLIBS_LIMIT_SEQUENCE_SIZE,
          class P,
          boost::mpl::na
        )
      >
      struct first_of :
        nth_of_c<0, BOOST_PP_ENUM_PARAMS(MPLLIBS_LIMIT_SEQUENCE_SIZE, P)>
      {};
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/impl/pop_front.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_IMPL_POP_FRONT_HPP
#define MPLLIBS_METAPARSE_V1_IMPL_POP_FRONT_HPP

// Copyright <NAME> (<EMAIL>)  2013.
// 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 <mpllibs/metaparse/config.hpp>
#include <mpllibs/metaparse/v1/fwd/string.hpp>

#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      namespace impl
      {
        template <class S>
        struct pop_front;

#ifdef MPLLIBS_VARIADIC_STRING
        template <char C, char... Cs>
        struct pop_front<string<C, Cs...>> : string<Cs...> {};
#else
        #ifdef MPLLIBS_POP_FRONT
        #  error MPLLIBS_POP_FRONT already defined
        #endif
        #define MPLLIBS_POP_FRONT(z, n, unused) \
          BOOST_PP_COMMA_IF(BOOST_PP_DEC(n)) BOOST_PP_CAT(C, n)

        template <BOOST_PP_ENUM_PARAMS(MPLLIBS_LIMIT_STRING_SIZE, int C)>
        struct
          pop_front<
            string<BOOST_PP_ENUM_PARAMS(MPLLIBS_LIMIT_STRING_SIZE, C)>
          > :
          string<
            BOOST_PP_REPEAT_FROM_TO(
              1,
              MPLLIBS_LIMIT_STRING_SIZE,
              MPLLIBS_POP_FRONT,
              ~
            ),
            MPLLIBS_NO_CHAR
          >
        {};

        #undef MPLLIBS_POP_FRONT
#endif
      }
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/one_of_c.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_ONE_OF_C_HPP
#define MPLLIBS_METAPARSE_V1_ONE_OF_C_HPP

// Copyright <NAME> (<EMAIL>)  2013.
// 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 <mpllibs/metaparse/v1/one_of.hpp>
#include <mpllibs/metaparse/v1/lit_c.hpp>

#include <boost/preprocessor/arithmetic/sub.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/tuple/eat.hpp>

#include <climits>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      #ifdef MPLLIBS_NO_SCALAR_VALUE
      #  error MPLLIBS_NO_SCALAR_VALUE already defined
      #endif
      #define MPLLIBS_NO_SCALAR_VALUE LONG_MAX

      template <
        BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
          MPLLIBS_LIMIT_ONE_OF_SIZE,
          long C,
          MPLLIBS_NO_SCALAR_VALUE
        )
      >
      struct one_of_c;

      #ifdef MPLLIBS_ONE_OF_C_LIT
      #  error MPLLIBS_ONE_OF_C_LIT already defined
      #endif
      #define MPLLIBS_ONE_OF_C_LIT(z, n, unused) lit_c<BOOST_PP_CAT(C, n)>

      #ifdef MPLLIBS_ONE_OF_C_CASE
      #  error MPLLIBS_ONE_OF_C_CASE already defined
      #endif
      #define MPLLIBS_ONE_OF_C_CASE(z, n, unused) \
        template <BOOST_PP_ENUM_PARAMS(n, long C)> \
        struct \
          one_of_c< \
            BOOST_PP_ENUM_PARAMS(n, C) \
            BOOST_PP_COMMA_IF(n) \
            BOOST_PP_ENUM( \
              BOOST_PP_SUB(MPLLIBS_LIMIT_ONE_OF_SIZE, n), \
              MPLLIBS_NO_SCALAR_VALUE BOOST_PP_TUPLE_EAT(3), \
              ~ \
            ) \
          > : \
          one_of<BOOST_PP_ENUM(n, MPLLIBS_ONE_OF_C_LIT, ~)> \
        {};

      BOOST_PP_REPEAT(MPLLIBS_LIMIT_ONE_OF_SIZE, MPLLIBS_ONE_OF_C_CASE, ~)

      #undef MPLLIBS_ONE_OF_C_CASE
      #undef MPLLIBS_ONE_OF_C_LIT
      #undef MPLLIBS_NO_SCALAR_VALUE
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/entire_input.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_ENTIRE_INPUT_HPP
#define MPLLIBS_METAPARSE_V1_ENTIRE_INPUT_HPP

// Copyright <NAME> (<EMAIL>)  2011.
// 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 <mpllibs/metaparse/v1/first_of.hpp>
#include <mpllibs/metaparse/v1/empty.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      template <class P>
      struct entire_input : first_of<P, empty<void> > {};
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/impl/at_c.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_IMPL_AT_C_HPP
#define MPLLIBS_METAPARSE_V1_IMPL_AT_C_HPP

// Copyright <NAME> (<EMAIL>)  2013.
// 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 <mpllibs/metaparse/config.hpp>
#include <mpllibs/metaparse/v1/fwd/string.hpp>

#include <boost/mpl/char.hpp>

#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      namespace impl
      {
        template <class S, int N>
        struct at_c;

#ifdef MPLLIBS_VARIADIC_STRING
        template <char C, char... Cs, int N>
        struct at_c<string<C, Cs...>, N> : at_c<string<Cs...>, N - 1> {};

        template <char C, char... Cs>
        struct at_c<string<C, Cs...>, 0> : boost::mpl::char_<C> {};
#else
        #ifdef MPLLIBS_STRING_CASE
        #  error MPLLIBS_STRING_CASE is already defined
        #endif
        #define MPLLIBS_STRING_CASE(z, n, unused) \
          template <BOOST_PP_ENUM_PARAMS(MPLLIBS_LIMIT_STRING_SIZE, int C)> \
          struct \
            at_c< \
              string<BOOST_PP_ENUM_PARAMS(MPLLIBS_LIMIT_STRING_SIZE,C)>, \
              n \
            > : \
            boost::mpl::char_<BOOST_PP_CAT(C, n)> \
          {};
      
        BOOST_PP_REPEAT(MPLLIBS_LIMIT_STRING_SIZE, MPLLIBS_STRING_CASE, ~)

        #undef MPLLIBS_STRING_CASE
#endif
      }
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/nth_of_c.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_NTH_OF_C_HPP
#define MPLLIBS_METAPARSE_V1_NTH_OF_C_HPP

// Copyright <NAME> (<EMAIL>)  2013.
// 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 <mpllibs/metaparse/v1/impl/nth_of_c.hpp>
#include <mpllibs/metaparse/limit_sequence_size.hpp>

#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
#include <boost/preprocessor/arithmetic/sub.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/tuple/eat.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      template <
        int N,
        BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
          MPLLIBS_LIMIT_SEQUENCE_SIZE,
          class P,
          boost::mpl::na
        )
      >
      struct nth_of_c;

      #ifdef MPLLIBS_NTH_OF_N
      #  error MPLLIBS_NTH_OF_N already defined
      #endif
      #define MPLLIBS_NTH_OF_N(z, n, unused) \
        template <int K BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, class P)> \
        struct nth_of_c< \
          K, \
          BOOST_PP_ENUM_PARAMS(n, P) \
          BOOST_PP_COMMA_IF(n) \
          BOOST_PP_ENUM( \
            BOOST_PP_SUB(MPLLIBS_LIMIT_SEQUENCE_SIZE, n), \
            boost::mpl::na BOOST_PP_TUPLE_EAT(3), \
            ~ \
          ) \
        > : \
          impl::BOOST_PP_CAT(nth_of_c, n)< \
            K BOOST_PP_COMMA_IF(n) \
            BOOST_PP_ENUM_PARAMS(n, P) \
          > \
        {};
      
      BOOST_PP_REPEAT(MPLLIBS_LIMIT_SEQUENCE_SIZE, MPLLIBS_NTH_OF_N, ~)
      
      #undef MPLLIBS_NTH_OF_N
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/keyword.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_KEYWORD_HPP
#define MPLLIBS_METAPARSE_V1_KEYWORD_HPP

// Copyright <NAME> (<EMAIL>)  2009 - 2010.
// 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 <mpllibs/metaparse/v1/impl/accepted_keyword.hpp>
#include <mpllibs/metaparse/v1/lit.hpp>
#include <mpllibs/metaparse/v1/return_.hpp>
#include <mpllibs/metaparse/v1/is_error.hpp>
#include <mpllibs/metaparse/v1/get_remaining.hpp>
#include <mpllibs/metaparse/v1/get_position.hpp>

#include <boost/mpl/if.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/empty.hpp>
#include <boost/mpl/pop_front.hpp>
#include <boost/mpl/front.hpp>
#include <boost/mpl/apply_wrap.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      // Does not consume/check anything after the keyword
      template <class Kw, class ResultType = impl::accepted_keyword>
      struct keyword
      {
      private:
        struct nonempty
        {
        private:
          typedef lit<typename boost::mpl::front<Kw>::type> next_char_parser;

          typedef
            keyword<typename boost::mpl::pop_front<Kw>::type, ResultType>
            rest_parser;
          
          template <class S, class Pos>
          struct apply_unchecked :
            boost::mpl::apply_wrap2<
              rest_parser,
              typename get_remaining<
                boost::mpl::apply_wrap2<next_char_parser, S, Pos>
              >::type,
              typename get_position<
                boost::mpl::apply_wrap2<next_char_parser, S, Pos>
              >::type
            >
          {};
        public:
          template <class S, class Pos>
          struct apply :
            boost::mpl::eval_if<
              typename is_error<
                boost::mpl::apply_wrap2<next_char_parser, S, Pos>
              >::type,
              boost::mpl::apply_wrap2<next_char_parser, S, Pos>,
              apply_unchecked<S, Pos>
            >
          {};
        };
      public:
        typedef keyword type;
        
        template <class S, class Pos>
        struct apply :
          boost::mpl::apply_wrap2<
            typename boost::mpl::if_<
              boost::mpl::empty<Kw>,
              return_<ResultType>,
              nonempty
            >::type,
            S,
            Pos
          >
        {};
      };
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/source_position_tag.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_SOURCE_POSITION_TAG_HPP
#define MPLLIBS_METAPARSE_V1_SOURCE_POSITION_TAG_HPP

//    Copyright <NAME> (<EMAIL>) 2013.
// 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 <mpllibs/metaparse/v1/fwd/source_position.hpp>
#include <mpllibs/metaparse/v1/fwd/get_prev_char.hpp>
#include <mpllibs/metaparse/v1/fwd/next_line.hpp>
#include <mpllibs/metaparse/v1/fwd/next_char.hpp>
#include <mpllibs/metaparse/v1/get_col.hpp>
#include <mpllibs/metaparse/v1/get_line.hpp>

#include <mpllibs/metamonad/tmp_tag.hpp>

#include <boost/mpl/int.hpp>
#include <boost/mpl/plus.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      struct source_position_tag : metamonad::tmp_tag<source_position_tag> {};
      
      template <>
      struct get_col_impl<source_position_tag>
      {
        template <class P>
        struct apply : P::col {};
      };

      template <>
      struct get_line_impl<source_position_tag>
      {
        template <class P>
        struct apply : P::line {};
      };

      
      template <>
      struct get_prev_char_impl<source_position_tag>
      {
        template <class P>
        struct apply : P::prev_char {};
      };
      
      
      template <>
      struct next_char_impl<source_position_tag>
      {
        template <class P, class Ch>
        struct apply :
          source_position<
            typename get_line<P>::type,
            typename boost::mpl::plus<
              typename get_col<P>::type,
              boost::mpl::int_<1>
            >::type,
            Ch
          >
        {};
      };

      template <>
      struct next_line_impl<source_position_tag>
      {
        template <class P, class Ch>
        struct apply :
          source_position<
            typename boost::mpl::plus<
              typename get_line<P>::type,
              boost::mpl::int_<1>
            >::type,
            boost::mpl::int_<1>,
            Ch
          >
        {};
      };
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/any1.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_ANY1_HPP
#define MPLLIBS_METAPARSE_V1_ANY1_HPP

// Copyright <NAME> (<EMAIL>)  2009 - 2010.
// 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 <mpllibs/metaparse/v1/foldr1.hpp>

#include <boost/mpl/vector.hpp>
#include <boost/mpl/push_front.hpp>
#include <boost/mpl/lambda.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      template <class P>
      struct any1 :
        foldr1<
          P,
          boost::mpl::vector<>,
          boost::mpl::lambda<
            boost::mpl::push_front<boost::mpl::_2, boost::mpl::_1>
          >::type
        >
      {};
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/middle_of.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_KEEP_MIDDLE_HPP
#define MPLLIBS_METAPARSE_V1_KEEP_MIDDLE_HPP

// Copyright <NAME> (<EMAIL>)  2009 - 2010.
// 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 <mpllibs/metaparse/v1/nth_of.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      template <class P1, class P2, class P3>
      struct middle_of : nth_of_c<1, P1, P2, P3> {};
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/fail.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_FAIL_HPP
#define MPLLIBS_METAPARSE_V1_FAIL_HPP

// Copyright <NAME> (<EMAIL>)  2009 - 2010.
// 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 <mpllibs/metaparse/v1/fail_tag.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      template <class Msg>
      struct fail
      {
        typedef fail type;
        
        template <class S, class Pos>
        struct apply
        {
          typedef fail_tag tag;
          typedef apply type;

          typedef Pos source_position;
          typedef Msg message;
        };
      };
    }
  }
}

#endif



<|start_filename|>lab/lab3.hpp<|end_filename|>
#ifndef LAB3_HPP
#define LAB3_HPP

// Copyright <NAME> (<EMAIL>)  2013.
// 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/xpressive/xpressive.hpp>

/*
 * Elements to build the regular expressions from
 */

// Empty regular expression
struct r_empty;

// Matches any character (.)
struct r_dot;

// Matches repetitions (E*)
template <class E>
struct r_star;

// Concatenates two regular expressions (AB)
template <class A, class B>
struct r_concat;

// Matches one specific character (C)
template <class C>
struct r_char;

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/parser_monad.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_PARSER_MONAD_HPP
#define MPLLIBS_METAPARSE_V1_PARSER_MONAD_HPP

// Copyright <NAME> (<EMAIL>)  2011.
// 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 <mpllibs/metaparse/v1/parser_tag.hpp>
#include <mpllibs/metaparse/v1/is_error.hpp>
#include <mpllibs/metaparse/v1/return_.hpp>
#include <mpllibs/metaparse/v1/get_result.hpp>
#include <mpllibs/metaparse/v1/get_remaining.hpp>
#include <mpllibs/metaparse/v1/get_position.hpp>
#include <mpllibs/metaparse/v1/fail.hpp>

#include <mpllibs/metamonad/monad.hpp>

#include <boost/mpl/always.hpp>
#include <boost/mpl/apply_wrap.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/eval_if.hpp>

namespace mpllibs
{
  namespace metamonad
  {
    namespace v1
    {
      template <>
      struct monad<metaparse::v1::parser_tag> :
        monad_defaults<metaparse::v1::parser_tag>
      {
        struct return_
        {
          typedef return_ type;
          
          template <class T>
          struct apply : metaparse::v1::return_<T> {};
        };
        
        struct bind
        {
        private:
          template <class P, class F>
          struct apply_impl
          {
          private:
            template <class PrevResult>
            struct apply_unchecked :
              boost::mpl::apply_wrap2<
                typename boost::mpl::apply<F, PrevResult>::type,
                typename metaparse::v1::get_remaining<PrevResult>::type,
                typename metaparse::v1::get_position<PrevResult>::type
              >
            {};
          public:
            typedef apply_impl type;
        
            template <class S, class Pos>
            struct apply :
              boost::mpl::eval_if<
                typename metaparse::v1::is_error<
                  boost::mpl::apply_wrap2<P, S, Pos>
                >::type,
                boost::mpl::apply_wrap2<P, S, Pos>,
                apply_unchecked<boost::mpl::apply_wrap2<P, S, Pos> >
              >
            {};
          };
        public:
          // P :: Parser
          // F :: previous_result -> Parser
          template <class P, class F>
          struct apply
          {
            typedef apply_impl<P, F> type;
          };
          
          typedef bind type;
        };

        struct fail
        {
          typedef fail type;

          template <class Msg>
          struct apply : metaparse::v1::fail<Msg> {};
        };
      };
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/sequence.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_SEQUENCE_HPP
#define MPLLIBS_METAPARSE_V1_SEQUENCE_HPP

// Copyright <NAME> (<EMAIL>)  2009 - 2010.
// 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 <mpllibs/metaparse/v1/impl/sequence.hpp>

#include <boost/preprocessor/comma_if.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
#include <boost/preprocessor/arithmetic/sub.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/tuple/eat.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      template <
        BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
          MPLLIBS_LIMIT_SEQUENCE_SIZE,
          class P,
          boost::mpl::na
        )
      >
      struct sequence;

      #ifdef MPLLIBS_SEQUENCE_N
      #  error MPLLIBS_SEQUENCE_N already defined
      #endif
      #define MPLLIBS_SEQUENCE_N(z, n, unused) \
        template <BOOST_PP_ENUM_PARAMS(n, class P)> \
        struct sequence< \
          BOOST_PP_ENUM_PARAMS(n, P) \
          BOOST_PP_COMMA_IF(n) \
          BOOST_PP_ENUM( \
            BOOST_PP_SUB(MPLLIBS_LIMIT_SEQUENCE_SIZE, n), \
            boost::mpl::na BOOST_PP_TUPLE_EAT(3), \
            ~ \
          ) \
        > : impl::BOOST_PP_CAT(sequence, n)<BOOST_PP_ENUM_PARAMS(n, P)> \
        {};
      
      BOOST_PP_REPEAT_FROM_TO(
        1,
        MPLLIBS_LIMIT_SEQUENCE_SIZE,
        MPLLIBS_SEQUENCE_N,
        ~
      )
      
      #undef MPLLIBS_SEQUENCE_N
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/token.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_TOKEN_HPP
#define MPLLIBS_METAPARSE_V1_TOKEN_HPP

// Copyright <NAME> (<EMAIL>)  2009 - 2010.
// 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 <mpllibs/metaparse/v1/space.hpp>
#include <mpllibs/metaparse/v1/any.hpp>
#include <mpllibs/metaparse/v1/first_of.hpp>

#include <boost/mpl/void.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      template <class P>
      struct token : first_of<P, any<space> > {};
    }
  }
}

#endif



<|start_filename|>doc/Makefile<|end_filename|>
# Copyright <NAME> (<EMAIL>)  2013.
# 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)

GEN_TOC = tools/gen_toc
DST = html
TOC ?= generate

ifeq ($(TOC), generate)
  TOC_STYLE = pandoc_html
else
  TOC_STYLE = none
endif

html : $(DST)/index.html

$(DST)/index.html : README.md
	$(GEN_TOC) -i $< -o - -t $(TOC_STYLE) \
	| grep -v secure.travis-ci.org \
        | sed 's/^[#] /% /' \
	| sed 's/https:\/\/raw\.github\.com\/sabel83\/metaparse_tutorial\/master\/doc\/html\///' \
	| pandoc --from markdown --to html -c style.css -o $@

clean :
	-rm $(DST)/index.html



<|start_filename|>lab/mpllibs/metaparse/v1/build_parser.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_BUILD_PARSER_HPP
#define MPLLIBS_METAPARSE_V1_BUILD_PARSER_HPP

// Copyright <NAME> (<EMAIL>)  2009 - 2010.
// 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 <mpllibs/metaparse/v1/fwd/build_parser.hpp>
#include <mpllibs/metaparse/v1/start.hpp>
#include <mpllibs/metaparse/v1/get_result.hpp>

#include <boost/mpl/apply.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      template <class P>
      struct build_parser
      {
        typedef build_parser type;
        
        template <class S>
        struct apply : get_result<boost::mpl::apply<P, S, start> > {};
      };
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/util/int_to_digit.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_UTIL_INT_TO_DIGIT_HPP
#define MPLLIBS_METAPARSE_V1_UTIL_INT_TO_DIGIT_HPP

// Copyright <NAME> (<EMAIL>)  2012.
// 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 <mpllibs/metaparse/v1/util/int_to_digit_c.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      namespace util
      {
        template <class N>
        struct int_to_digit : int_to_digit_c<N::type::value> {};
      }
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/iterate.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_ITERATE_HPP
#define MPLLIBS_METAPARSE_V1_ITERATE_HPP

// Copyright <NAME> (<EMAIL>)  2009 - 2010.
// 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 <mpllibs/metaparse/v1/iterate_c.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      template <class P, class N>
      struct iterate : iterate_c<P, N::type::value> {};
    }
  }
}

#endif



<|start_filename|>lab/Makefile<|end_filename|>
# Copyright <NAME> (<EMAIL>)  2013.
# 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)

INCLUDES += .
CXXFLAGS += -Wall
CXXFLAGS += -Werror
CXXFLAGS += -ansi
CXXFLAGS += -std=c++0x

# We need it for dependency file generation
CXXFLAGS += -MMD
CXXFLAGS += -MP

TEST = regex_test.o

CPPS = $(wildcard *.cpp)
OBJECTS = $(CPPS:.cpp=.o)
EXECS = $(filter-out $(TEST:.o=), $(OBJECTS:.o=))
DEPS = $(OBJECTS:.o=.d)

test : build
	$(foreach e, $(EXECS), ./$(e) &&) true

build : $(EXECS)

$(OBJECTS) : %.o : %.cpp
	$(CXX) -c $(CFLAGS) $(CXXFLAGS) $(foreach i, $(INCLUDES), -I$(i) ) $<
	sed -i -e '1s,\($*\)\.o[ :]*,\1.o $*.d: ,' $*.d

$(EXECS) : % : %.o $(TEST)
	$(CXX) -o $@ $< $(TEST)

clean :
	-rm $(EXECS) $(OBJECTS) $(DEPS)

all : clean build

-include $(DEPS)

# Remove all comments from the test source files
REMOVE_COMMENT_TARGETS = $(addprefix remove_comment_, $(CPPS))

$(REMOVE_COMMENT_TARGETS) : remove_comment_% : %
	sed -i 's/^\/\/\([ ]*&&\)/\1/' $<
	sed -i 's/\/\*\|\*\///' $<

remove_comments : $(REMOVE_COMMENT_TARGETS)



<|start_filename|>lab/mpllibs/metaparse/v1/foldr.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_FOLDR_HPP
#define MPLLIBS_METAPARSE_V1_FOLDR_HPP

// Copyright <NAME> (<EMAIL>) 2011 - 2012.
// 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 <mpllibs/metaparse/v1/return_.hpp>
#include <mpllibs/metaparse/v1/foldrp.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      template <class P, class State, class BackwardOp>
      struct foldr : foldrp<P, return_<State>, BackwardOp> {};
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/safe_printf/v1/printf.hpp<|end_filename|>
#ifndef MPLLIBS_SAFE_PRINTF_V1_PRINTF_HPP
#define MPLLIBS_SAFE_PRINTF_V1_PRINTF_HPP

// Copyright <NAME> (<EMAIL>)  2009 - 2010.
// 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 <mpllibs/safe_printf/v1/fwd/printf.hpp>
#include <mpllibs/safe_printf/v1/valid_arguments.hpp>

#include <boost/mpl/string.hpp>
#include <boost/mpl/vector.hpp>

#include <boost/static_assert.hpp>

#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/comma_if.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>

#include <cstdio>

namespace mpllibs
{
  namespace safe_printf
  {
    namespace v1
    {
      #ifdef MPLLIBS_PRINTF_TEMPLATE
      #  error MPLLIBS_PRINTF_TEMPLATE already defined
      #endif
      #define MPLLIBS_PRINTF_TEMPLATE(n) \
        template < \
          class FormatString \
          BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, class T) \
        >
  
      #ifdef MPLLIBS_PRINTF_BOX
      #  error MPLLIBS_PRINTF_BOX already defined
      #endif
      #define MPLLIBS_PRINTF_BOX(z, n, unused) \
        metamonad::box<BOOST_PP_CAT(T, n)>
  
      #ifdef MPLLIBS_PRINTF_ASSERT
      #  error MPLLIBS_PRINTF_ASSERT already defined
      #endif
      #define MPLLIBS_PRINTF_ASSERT(n) \
        BOOST_STATIC_ASSERT(( \
          valid_arguments< \
            FormatString, \
            boost::mpl::vector<BOOST_PP_ENUM(n, MPLLIBS_PRINTF_BOX, ~)> \
          >::type::value \
        )) \
  
      #ifdef MPLLIBS_PRINTF_ARGS
      #  error MPLLIBS_PRINTF_ARGS already defined
      #endif
      #define MPLLIBS_PRINTF_ARGS(n) \
        boost::mpl::c_str<FormatString>::type::value BOOST_PP_COMMA_IF(n) \
        BOOST_PP_ENUM_PARAMS(n, t) \
      
      #ifdef MPLLIBS_PRINTF
      #  error MPLLIBS_PRINTF already defined
      #endif
      #define MPLLIBS_PRINTF(z, n, unused) \
        MPLLIBS_PRINTF_TEMPLATE(n) \
        int printf(BOOST_PP_ENUM_BINARY_PARAMS(n, T, t)) \
        { \
          MPLLIBS_PRINTF_ASSERT(n); \
          return ::printf(MPLLIBS_PRINTF_ARGS(n)); \
        } \
        \
        MPLLIBS_PRINTF_TEMPLATE(n) \
        int fprintf( \
          FILE* stream BOOST_PP_COMMA_IF(n) \
          BOOST_PP_ENUM_BINARY_PARAMS(n, T, t) \
        ) \
        { \
          MPLLIBS_PRINTF_ASSERT(n); \
          return ::fprintf(stream, MPLLIBS_PRINTF_ARGS(n)); \
        } \
        \
        MPLLIBS_PRINTF_TEMPLATE(n) \
        int sprintf( \
          char* s BOOST_PP_COMMA_IF(n) \
          BOOST_PP_ENUM_BINARY_PARAMS(n, T, t) \
        ) \
        { \
          MPLLIBS_PRINTF_ASSERT(n); \
          return ::sprintf(s, MPLLIBS_PRINTF_ARGS(n)); \
        }
  
      #ifdef _MSC_VER
      #  pragma warning(push)
      #  pragma warning(disable: 4996)
      #endif
  
      BOOST_PP_REPEAT(MPLLIBS_PRINTF_MAX_ARGUMENT, MPLLIBS_PRINTF, ~)
  
      #ifdef _MSC_VER
      #  pragma warning(pop)
      #endif
      
      #undef MPLLIBS_PRINTF
      #undef MPLLIBS_PRINTF_BOX
      #undef MPLLIBS_PRINTF_ARGS
      #undef MPLLIBS_PRINTF_ASSERT
      #undef MPLLIBS_PRINTF_TEMPLATE
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/next_char.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_NEXT_CHAR_HPP
#define MPLLIBS_METAPARSE_V1_NEXT_CHAR_HPP

//    Copyright <NAME> (<EMAIL>) 2011.
// 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 <mpllibs/metaparse/v1/fwd/next_char.hpp>

#include <boost/mpl/apply_wrap.hpp>
#include <boost/mpl/tag.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      template <class P, class Ch>
      struct next_char :
        boost::mpl::apply_wrap2<
          next_char_impl<typename boost::mpl::tag<typename P::type>::type>,
          typename P::type,
          typename Ch::type
        >
      {};
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/impl/split_at_c.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_IMPL_SPLIT_AT_C_HPP
#define MPLLIBS_METAPARSE_V1_IMPL_SPLIT_AT_C_HPP

// Copyright <NAME> (<EMAIL>)  2013.
// 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 <mpllibs/metaparse/config.hpp>
#include <mpllibs/metaparse/v1/fwd/string.hpp>
#include <mpllibs/metaparse/v1/impl/push_front_c.hpp>

#include <boost/preprocessor/arithmetic/add.hpp>
#include <boost/preprocessor/arithmetic/sub.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>

#include <boost/mpl/pair.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      namespace impl
      {
        template <int N, class S>
        struct split_at_c;

#ifdef MPLLIBS_VARIADIC_STRING
        template <int N, char C, char... Cs>
        struct split_at_c<N, string<C, Cs...>> :
          boost::mpl::pair<
            typename push_front_c<
              typename split_at_c<N - 1, string<Cs...>>::type::first,
              C
            >::type,
            typename split_at_c<N - 1, string<Cs...>>::type::second
          >
        {};

        template <char C, char... Cs>
        struct split_at_c<0, string<C, Cs...>> :
          boost::mpl::pair<string<>, string<C, Cs...>>
        {};

        template <char... Cs>
        struct split_at_c<0, string<Cs...>> :
          boost::mpl::pair<string<>, string<Cs...>>
        {};
#else
        #ifdef MPLLIBS_ARG
        #  error MPLLIBS_ARG already defined
        #endif
        #define MPLLIBS_ARG(z, n, d) BOOST_PP_CAT(C, BOOST_PP_ADD(n, d))

        #ifdef MPLLIBS_SPLIT_AT
        #  error MPLLIBS_SPLIT_AT already defined
        #endif
        #define MPLLIBS_SPLIT_AT(z, n, unused) \
          template <BOOST_PP_ENUM_PARAMS(MPLLIBS_LIMIT_STRING_SIZE, int C)> \
          struct \
            split_at_c< \
              n, \
              string<BOOST_PP_ENUM_PARAMS(MPLLIBS_LIMIT_STRING_SIZE, C)> \
            > : \
            boost::mpl::pair< \
              string<BOOST_PP_ENUM_PARAMS(n, C)>, \
              string< \
                BOOST_PP_ENUM( \
                  BOOST_PP_SUB(MPLLIBS_LIMIT_STRING_SIZE, n), \
                  MPLLIBS_ARG, \
                  n \
                ) \
              > \
            > \
          {};

        BOOST_PP_REPEAT(MPLLIBS_LIMIT_STRING_SIZE, MPLLIBS_SPLIT_AT, ~)

        #undef MPLLIBS_SPLIT_AT
        #undef MPLLIBS_ARG
#endif
      }
    }
  }
}

#endif



<|start_filename|>lab/lab6.hpp<|end_filename|>
#ifndef LAB6_HPP
#define LAB6_HPP

// Copyright <NAME> (<EMAIL>)  2013.
// 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 <lab3.hpp>

/*
 * Semantic actions
 */

struct build_char_;
struct build_unary_item;
struct build_reg_exp;

/*
 * The parser
 *
 * reg_exp ::= unary_item*
 * unary_item ::= item '*'?
 * item ::= any | bracket_exp | char_
 * any ::= '.'
 * bracket_exp ::= '(' reg_exp ')'
 * char_ ::= number | letter
 * number ::= '0'..'9'
 * letter ::= 'a'..'z' | 'A'..'Z'
 * 
 */


#ifdef REGEX
  #error REGEX already defined
#endif

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/foldl.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_FOLDL_HPP
#define MPLLIBS_METAPARSE_V1_FOLDL_HPP

// Copyright <NAME> (<EMAIL>)  2011.
// 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 <mpllibs/metaparse/v1/return_.hpp>
#include <mpllibs/metaparse/v1/is_error.hpp>
#include <mpllibs/metaparse/v1/get_position.hpp>
#include <mpllibs/metaparse/v1/get_result.hpp>
#include <mpllibs/metaparse/v1/get_remaining.hpp>

#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/apply_wrap.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      template <class P, class State, class ForwardOp>
      struct foldl
      {
      private:
        template <class Res>
        struct apply_unchecked :
          // foldl never returns error
          // I need to use apply_wrap, and not apply, because apply would
          // build a metafunction class from foldl<P, State, ForwardOp>
          // when ForwardOp is a lambda expression.
          boost::mpl::apply_wrap2<
            foldl<
              P,
              boost::mpl::apply<
                ForwardOp,
                typename get_result<Res>::type,
                typename State::type
              >,
              ForwardOp
            >,
            typename get_remaining<Res>::type,
            typename get_position<Res>::type
          >
        {};
      public:
        typedef foldl type;
      
        template <class S, class Pos>
        struct apply :
          boost::mpl::eval_if<
            typename is_error<boost::mpl::apply<P, S, Pos> >::type,
            boost::mpl::apply_wrap2<return_<typename State::type>, S, Pos>,
            apply_unchecked<boost::mpl::apply<P, S, Pos> >
          >
        {};
      };
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/impl/concat.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_IMPL_CONCAT_HPP
#define MPLLIBS_METAPARSE_V1_IMPL_CONCAT_HPP

// Copyright <NAME> (<EMAIL>)  2013.
// 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 <mpllibs/metaparse/config.hpp>
#include <mpllibs/metaparse/v1/fwd/string.hpp>

#include <boost/preprocessor/arithmetic/dec.hpp>
#include <boost/preprocessor/arithmetic/inc.hpp>
#include <boost/preprocessor/arithmetic/mul.hpp>
#include <boost/preprocessor/arithmetic/sub.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      namespace impl
      {
        template <class A, class B>
        struct concat;

#ifdef MPLLIBS_VARIADIC_STRING
        template <char... As, char... Bs>
        struct concat<string<As...>, string<Bs...>> : string<As..., Bs...> {};
#else
        template <class A, class B>
        struct concat_impl;

        #ifdef MPLLIBS_ARG
        #  error MPLLIBS_ARG already defined
        #endif
        #define MPLLIBS_ARG(z, n, unused) BOOST_PP_CAT(B, BOOST_PP_INC(n))

        #ifdef MPLLIBS_CONCAT
        #  error MPLLIBS_CONCAT already defined
        #endif
        #define MPLLIBS_CONCAT(z, n, unused) \
          template < \
            BOOST_PP_ENUM_PARAMS(n, int A) BOOST_PP_COMMA_IF(n) \
            BOOST_PP_ENUM_PARAMS(MPLLIBS_LIMIT_STRING_SIZE, int B) \
          > \
          struct \
            concat_impl< \
              string< \
                BOOST_PP_ENUM_PARAMS(n, A) \
                BOOST_PP_COMMA_IF( \
                  BOOST_PP_MUL(BOOST_PP_SUB(MPLLIBS_LIMIT_STRING_SIZE, n), n) \
                ) \
                BOOST_PP_ENUM( \
                  BOOST_PP_SUB(MPLLIBS_LIMIT_STRING_SIZE, n), \
                  MPLLIBS_NO_CHAR BOOST_PP_TUPLE_EAT(3), \
                  ~ \
                ) \
              >, \
              string<BOOST_PP_ENUM_PARAMS(MPLLIBS_LIMIT_STRING_SIZE, B)> \
            > : \
            concat< \
              string<BOOST_PP_ENUM_PARAMS(n, A) BOOST_PP_COMMA_IF(n) B0>, \
              string< \
                BOOST_PP_ENUM( \
                  BOOST_PP_DEC(MPLLIBS_LIMIT_STRING_SIZE), \
                  MPLLIBS_ARG, \
                  ~ \
                ) \
              > \
            > \
          {};

        BOOST_PP_REPEAT(MPLLIBS_LIMIT_STRING_SIZE, MPLLIBS_CONCAT, ~)

        #undef MPLLIBS_ARG
        #undef MPLLIBS_CONCAT

        template <class S>
        struct concat<S, string<> > : S {};

        template <class A, class B>
        struct concat : concat_impl<A, B> {};
#endif
      }
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/util/in_range.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_UTIL_IN_RANGE_HPP
#define MPLLIBS_METAPARSE_V1_UTIL_IN_RANGE_HPP

// Copyright <NAME> (<EMAIL>)  2009 - 2010.
// 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/less_equal.hpp>
#include <boost/mpl/comparison.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/quote.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      namespace util
      {
        template <class LowerBound, class UpperBound>
        struct in_range
        {
          typedef in_range type;
        
          template <class Item>
          struct apply :
            boost::mpl::and_<
              boost::mpl::less_equal<LowerBound, Item>,
              boost::mpl::less_equal<Item, UpperBound>
            >
          {};
        };
      }
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/if_.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_IF__HPP
#define MPLLIBS_METAPARSE_V1_IF__HPP

// Copyright <NAME> (<EMAIL>)  2009 - 2010.
// 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 <mpllibs/metaparse/v1/return_.hpp>
#include <mpllibs/metaparse/v1/is_error.hpp>

#include <boost/mpl/apply.hpp>
#include <boost/mpl/apply_wrap.hpp>
#include <boost/mpl/if.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      template <class P, class T, class F>
      struct if_
      {
        typedef if_ type;
        
        template <class S, class Pos>
        struct apply :
          boost::mpl::apply_wrap2<
            return_<
              typename boost::mpl::if_<
                is_error<boost::mpl::apply<P, S, Pos> >,
                F,
                T
              >::type
            >,
            S,
            Pos
          >
        {};
      };
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/impl/empty_string.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_IMPL_EMPTY_STRING_HPP
#define MPLLIBS_METAPARSE_V1_IMPL_EMPTY_STRING_HPP

// Copyright <NAME> (<EMAIL>)  2013.
// 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 <mpllibs/metaparse/config.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      namespace impl
      {
        template <class Ignore = int>
        struct empty_string
        {
          typedef empty_string type;

          #if defined MPLLIBS_USE_CONSTEXPR && !defined MPLLIBS_NO_CONSTEXPR_C_STR
            static constexpr const char value[1] = {0};
          #else
            static const char value[1];
          #endif
        };

        #if defined MPLLIBS_USE_CONSTEXPR && !defined MPLLIBS_NO_CONSTEXPR_C_STR
          template <class Ignore>
          constexpr const char empty_string<Ignore>::value[1];
        #else
          template <class Ignore>
          const char empty_string<Ignore>::value[1] = {0};
        #endif
      }
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/string.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_STRING_HPP
#define MPLLIBS_METAPARSE_V1_STRING_HPP

// Copyright <NAME> (<EMAIL>)  2012.
// 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 <mpllibs/metaparse/config.hpp>
#include <mpllibs/metaparse/v1/fwd/string.hpp>
#include <mpllibs/metaparse/v1/string_tag.hpp>
#include <mpllibs/metaparse/v1/impl/string_iterator.hpp>
#include <mpllibs/metaparse/v1/impl/empty_string.hpp>
#include <mpllibs/metaparse/v1/impl/size.hpp>
#include <mpllibs/metaparse/v1/impl/pop_front.hpp>
#include <mpllibs/metaparse/v1/impl/push_front_c.hpp>
#include <mpllibs/metaparse/v1/impl/push_back_c.hpp>
#include <mpllibs/metaparse/v1/impl/pop_back.hpp>

#include <mpllibs/boost.hpp>

#include <boost/preprocessor/arithmetic/sub.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <boost/preprocessor/tuple/eat.hpp>

#include <boost/type_traits/is_same.hpp>

/*
 * The string type
 */

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
#ifdef MPLLIBS_VARIADIC_STRING
      template <char... Cs>
      struct string
      {
        typedef string type;
        typedef string_tag tag;
      };
#else
      template <BOOST_PP_ENUM_PARAMS(MPLLIBS_LIMIT_STRING_SIZE, int C)>
      struct string
      {
        typedef string type;
        typedef string_tag tag;
      };
#endif
    }
  }
}

/*
 * Boost.MPL overloads
 */

namespace MPLLIBS_BOOST_NAMESPACE
{
  namespace mpl
  {
    // push_back
    template <class S>
    struct push_back_impl;

    template <>
    struct push_back_impl<mpllibs::metaparse::v1::string_tag>
    {
      typedef push_back_impl type;

      template <class S, class C>
      struct apply :
        mpllibs::metaparse::v1::impl::push_back_c<
          typename S::type,
          C::type::value
        >
      {};
    };

    // pop_back
    template <class S>
    struct pop_back_impl;

    template <>
    struct pop_back_impl<mpllibs::metaparse::v1::string_tag>
    {
      typedef pop_back_impl type;

      template <class S>
      struct apply : mpllibs::metaparse::v1::impl::pop_back<S> {};
    };

    // push_front
    template <class S>
    struct push_front_impl;

    template <>
    struct push_front_impl<mpllibs::metaparse::v1::string_tag>
    {
      typedef push_front_impl type;

      template <class S, class C>
      struct apply :
        mpllibs::metaparse::v1::impl::push_front_c<
          typename S::type,
          C::type::value
        >
      {};
    };

    // pop_front
    template <class S>
    struct pop_front_impl;

    template <>
    struct pop_front_impl<mpllibs::metaparse::v1::string_tag>
    {
      typedef pop_front_impl type;

      template <class S>
      struct apply : mpllibs::metaparse::v1::impl::pop_front<S> {};
    };

    // clear
    template <class S>
    struct clear_impl;

    template <>
    struct clear_impl<mpllibs::metaparse::v1::string_tag>
    {
      typedef clear_impl type;

      template <class S>
      struct apply : mpllibs::metaparse::v1::string<> {};
    };

    // begin
    template <class S>
    struct begin_impl;

    template <>
    struct begin_impl<mpllibs::metaparse::v1::string_tag>
    {
      typedef begin_impl type;

      template <class S>
      struct apply :
        mpllibs::metaparse::v1::impl::string_iterator<typename S::type, 0>
      {};
    };

    // end
    template <class S>
    struct end_impl;

    template <>
    struct end_impl<mpllibs::metaparse::v1::string_tag>
    {
      typedef end_impl type;

      template <class S>
      struct apply :
        mpllibs::metaparse::v1::impl::string_iterator<
          typename S::type,
          mpllibs::metaparse::v1::impl::size<typename S::type>::type::value
        >
      {};
    };

    // equal_to
    template <class A, class B>
    struct equal_to_impl;

    template <>
    struct equal_to_impl<
      mpllibs::metaparse::v1::string_tag,
      mpllibs::metaparse::v1::string_tag
    >
    {
      typedef equal_to_impl type;

      template <class A, class B>
      struct apply : boost::is_same<typename A::type, typename B::type> {};
    };

    template <class T>
    struct equal_to_impl<mpllibs::metaparse::v1::string_tag, T>
    {
      typedef equal_to_impl type;
      
      template <class, class>
      struct apply : false_ {};
    };
    
    template <class T>
    struct equal_to_impl<T, mpllibs::metaparse::v1::string_tag> :
      equal_to_impl<mpllibs::metaparse::v1::string_tag, T>
    {};

    // c_str
    template <class S>
    struct c_str;

#ifdef MPLLIBS_VARIADIC_STRING
    template <char... Cs>
    struct c_str<mpllibs::metaparse::v1::string<Cs...>>
    {
      typedef c_str type;
      #if defined MPLLIBS_USE_CONSTEXPR && !defined MPLLIBS_NO_CONSTEXPR_C_STR
        static constexpr const char value[sizeof...(Cs)] = {Cs...};
      #else
        static const char value[sizeof...(Cs)];
      #endif
    };

    template <>
    struct c_str<mpllibs::metaparse::v1::string<>> :
      mpllibs::metaparse::v1::impl::empty_string<>
    {};

    #if defined MPLLIBS_USE_CONSTEXPR && !defined MPLLIBS_NO_CONSTEXPR_C_STR
      template <char... Cs>
      constexpr const char
        c_str<mpllibs::metaparse::v1::string<Cs...>>::value[];
    #else
      template <char... Cs>
      const char c_str<mpllibs::metaparse::v1::string<Cs...>>::value[]
        = {Cs...};
    #endif

#else
    template <BOOST_PP_ENUM_PARAMS(MPLLIBS_LIMIT_STRING_SIZE, int C)>
    struct c_str<
      mpllibs::metaparse::v1::string<
        BOOST_PP_ENUM_PARAMS(MPLLIBS_LIMIT_STRING_SIZE, C)
      >
    >
    {
      typedef c_str type;
      static MPLLIBS_CONSTEXPR const char value[MPLLIBS_LIMIT_STRING_SIZE + 1]
      #ifdef MPLLIBS_USE_CONSTEXPR
        = {BOOST_PP_ENUM_PARAMS(MPLLIBS_LIMIT_STRING_SIZE, C), 0}
      #endif
        ;
    };

    template <BOOST_PP_ENUM_PARAMS(MPLLIBS_LIMIT_STRING_SIZE, int C)>
    MPLLIBS_CONSTEXPR const char
      c_str<
        mpllibs::metaparse::v1::string<
          BOOST_PP_ENUM_PARAMS(MPLLIBS_LIMIT_STRING_SIZE, C)
        >
      >::value[MPLLIBS_LIMIT_STRING_SIZE + 1]
      #ifndef MPLLIBS_USE_CONSTEXPR
        = {BOOST_PP_ENUM_PARAMS(MPLLIBS_LIMIT_STRING_SIZE, C), 0}
      #endif
        ;

    template <>
    struct c_str<mpllibs::metaparse::v1::string<> > :
      mpllibs::metaparse::v1::impl::empty_string<>
    {
      typedef c_str type;
    };

    #ifdef MPLLIBS_DEF
    #  error MPLLIBS_DEF already defined
    #endif
    #define MPLLIBS_DEF(n) = {BOOST_PP_ENUM_PARAMS(n, C) BOOST_PP_COMMA_IF(n) 0}

    #ifdef MPLLIBS_STRING_DECLARE
    #  error MPLLIBS_STRING_DECLARE already defined
    #endif
    #ifdef MPLLIBS_STRING_DEFINE
    #  error MPLLIBS_STRING_DECLARE already defined
    #endif
    #ifdef MPLLIBS_USE_CONSTEXPR
    #  define MPLLIBS_STRING_DECLARE(n) MPLLIBS_DEF(n)
    #  define MPLLIBS_STRING_DEFINE(n)
    #else
    #  define MPLLIBS_STRING_DECLARE(n)
    #  define MPLLIBS_STRING_DEFINE(n) MPLLIBS_DEF(n)
    #endif

    #ifdef MPLLIBS_STRING_CASE
    #  error MPLLIBS_STRING_CASE is already defined
    #endif
    #define MPLLIBS_STRING_CASE(z, n, unused) \
      template <BOOST_PP_ENUM_PARAMS(n, int C)> \
      struct \
        c_str< \
          mpllibs::metaparse::v1::string< \
            BOOST_PP_ENUM_PARAMS(n, C) BOOST_PP_COMMA_IF(n) \
            BOOST_PP_ENUM( \
              BOOST_PP_SUB(MPLLIBS_LIMIT_STRING_SIZE, n), \
              MPLLIBS_NO_CHAR BOOST_PP_TUPLE_EAT(3), \
              ~ \
            ) \
          > \
        > \
      { \
        typedef c_str type; \
        static MPLLIBS_CONSTEXPR const char value[n + 1] \
          MPLLIBS_STRING_DECLARE(n); \
      }; \
      \
      template <BOOST_PP_ENUM_PARAMS(n, int C)> \
      MPLLIBS_CONSTEXPR const char c_str< \
        mpllibs::metaparse::v1::string< \
          BOOST_PP_ENUM_PARAMS(n, C) BOOST_PP_COMMA_IF(n) \
          BOOST_PP_ENUM( \
            BOOST_PP_SUB(MPLLIBS_LIMIT_STRING_SIZE, n), \
            MPLLIBS_NO_CHAR BOOST_PP_TUPLE_EAT(3), \
            ~ \
          ) \
        > \
      >::value[n + 1] MPLLIBS_STRING_DEFINE(n);

    BOOST_PP_REPEAT_FROM_TO(
      1,
      MPLLIBS_LIMIT_STRING_SIZE,
      MPLLIBS_STRING_CASE,
      ~
    )

    #undef MPLLIBS_STRING_CASE
    #undef MPLLIBS_STRING_DECLARE
    #undef MPLLIBS_STRING_DEFINE
    #undef MPLLIBS_DEF
#endif
  }
}

/*
 * The MPLLIBS_STRING macro
 */

#if defined MPLLIBS_USE_CONSTEXPR && !defined MPLLIBS_CONFIG_NO_MPLLIBS_STRING

#include <mpllibs/metaparse/v1/impl/remove_trailing_no_chars.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      namespace impl
      {
        template <int Len, class T>
        constexpr int string_at(const T (&s)[Len], int n)
        {
          return n >= Len - 1 ? MPLLIBS_NO_CHAR : s[n];
        }
      }
    }
  }
}

  #ifdef MPLLIBS_V1_STRING_N
  #  error MPLLIBS_V1_STRING_N already defined
  #endif
  #define MPLLIBS_V1_STRING_N(z, n, s) \
    mpllibs::metaparse::v1::impl::string_at((s), n)

  #ifdef MPLLIBS_V1_STRING
  #  error MPLLIBS_V1_STRING already defined
  #endif
  #define MPLLIBS_V1_STRING(s) \
    mpllibs::metaparse::v1::impl::remove_trailing_no_chars< \
      mpllibs::metaparse::v1::string< \
        BOOST_PP_ENUM(MPLLIBS_LIMIT_STRING_SIZE, MPLLIBS_V1_STRING_N, s) \
      > \
    >::type

#else

  // Include it only when it is needed
  #include <boost/static_assert.hpp>

  #ifdef MPLLIBS_V1_STRING
  #  error MPLLIBS_V1_STRING already defined
  #endif
  #define MPLLIBS_V1_STRING(s) \
    BOOST_STATIC_ASSERT_MSG(false, "MPLLIBS_STRING is not supported")

  #define MPLLIBS_V1_CONFIG_NO_MPLLIBS_STRING

#endif

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/lit_c.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_LIT_C_HPP
#define MPLLIBS_METAPARSE_V1_LIT_C_HPP

// Copyright <NAME> (<EMAIL>)  2009 - 2010.
// 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 <mpllibs/metaparse/v1/lit.hpp>

#include <boost/mpl/char.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      template <char C>
      struct lit_c : lit<boost::mpl::char_<C> > {};
    }
  }
}

#endif




<|start_filename|>lab/mpllibs/metaparse/v1/iterate_c.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_ITERATE_C_HPP
#define MPLLIBS_METAPARSE_V1_ITERATE_C_HPP

// Copyright <NAME> (<EMAIL>)  2011.
// 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 <mpllibs/metaparse/v1/impl/iterate_impl.hpp>

#include <boost/mpl/deque.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      template <class P, int N>
      struct iterate_c : impl::iterate_impl<N, P, boost::mpl::deque<> > {};
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/util/is_digit.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_UTIL_IS_DIGIT_HPP
#define MPLLIBS_METAPARSE_V1_UTIL_IS_DIGIT_HPP

// Copyright <NAME> (<EMAIL>)  2009 - 2010.
// 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 <mpllibs/metaparse/v1/util/in_range.hpp>

#include <boost/mpl/char.hpp>
#include <boost/mpl/vector.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      namespace util
      {
        template <class C = boost::mpl::na>
        struct is_digit :
          in_range<boost::mpl::char_<'0'>, boost::mpl::char_<'9'> >::apply<C>
        {};

        template <>
        struct is_digit<boost::mpl::na>
        {
          typedef is_digit type;

          template <class C = boost::mpl::na>
          struct apply : is_digit<C> {};
        };
      }
    }
  }
}

#endif



<|start_filename|>solution/lab3.hpp<|end_filename|>
#ifndef LAB3_HPP
#define LAB3_HPP

// Copyright <NAME> (<EMAIL>)  2013.
// 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/xpressive/xpressive.hpp>

#include <boost/proto/deep_copy.hpp>

/*
 * Elements to build the regular expressions from
 */

#ifdef RUN
  #error RUN already defined
#endif
#define RUN(...) static decltype(__VA_ARGS__) run() { return (__VA_ARGS__); }

// Empty regular expression
struct r_empty
{
  typedef r_empty type;

  RUN(boost::xpressive::nil)
};

// Matches any character (.)
struct r_dot
{
  typedef r_dot type;

  RUN(boost::xpressive::_)
};

// Matches repetitions (E*)
template <class E>
struct r_star
{
  typedef r_star type;

  RUN(boost::proto::deep_copy(*E::type::run()))
};

// Concatenates two regular expressions (AB)
template <class A, class B>
struct r_concat
{
  typedef r_concat type;

  RUN(boost::proto::deep_copy(A::type::run() >> B::type::run()))
};

// Matches one specific character (C)
template <class C>
struct r_char
{
  typedef r_char type;

  RUN(boost::xpressive::as_xpr(C::type::value))
};

// Used by this header only
#undef RUN

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/util/digit_to_int.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_UTIL_DIGIT_TO_INT_HPP
#define MPLLIBS_METAPARSE_V1_UTIL_DIGIT_TO_INT_HPP

// Copyright <NAME> (<EMAIL>)  2009 - 2010.
// 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 <mpllibs/metaparse/v1/util/digit_to_int_c.hpp>

#include <boost/mpl/vector.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      namespace util
      {
        template <class D = boost::mpl::na>
        struct digit_to_int : digit_to_int_c<D::type::value> {};

        template <>
        struct digit_to_int<boost::mpl::na>
        {
          typedef digit_to_int type;
          
          template <class D = boost::mpl::na>
          struct apply : digit_to_int<D> {};
        };
      }
    }
  }
}

#endif



<|start_filename|>lab/tmp_test.hpp<|end_filename|>
#ifndef TMP_TEST_HPP
#define TMP_TEST_HPP

// Copyright <NAME> (<EMAIL>)  2013.
// 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/type_traits/is_same.hpp>

#include <iostream>

#ifdef REMOVE_BRACKET
  #error REMOVE_BRACKET already defined
#endif
#define REMOVE_BRACKET(...) __VA_ARGS__

#ifdef TEST_SAME
  #error TEST_SAME already defined
#endif
#define TEST_SAME(A, B) \
  (test_same<REMOVE_BRACKET A, REMOVE_BRACKET B>(#A, #B, __FILE__, __LINE__))

template <class A, class B>
bool test_same(
  const char* a_,
  const char* b_,
  const char* fn_,
  unsigned int line_
)
{
  const bool ok = boost::is_same<A, B>::type::value;
  if (!ok)
  {
    std::cout
      << fn_ << ":" << line_ << " ERROR: " << a_ << " != " << b_ << std::endl;
  }
  return ok;
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/source_position.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_SOURCE_POSITION_HPP
#define MPLLIBS_METAPARSE_V1_SOURCE_POSITION_HPP

//    Copyright <NAME> (<EMAIL>) 2011.
// 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 <mpllibs/metaparse/v1/fwd/source_position.hpp>
#include <mpllibs/metaparse/v1/source_position_tag.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      template <class Line, class Col, class PrevChar>
      struct source_position
      {
        typedef source_position_tag tag;
        typedef source_position type;
        
        typedef Line line;
        typedef Col col;
        typedef PrevChar prev_char;
      };
    }
  }
}

#endif



<|start_filename|>lab/mpllibs/metaparse/v1/impl/fwd/iterate_impl.hpp<|end_filename|>
#ifndef MPLLIBS_METAPARSE_V1_IMPL_FWD_ITERATE_IMPL_HPP
#define MPLLIBS_METAPARSE_V1_IMPL_FWD_ITERATE_IMPL_HPP

// Copyright <NAME> (<EMAIL>)  2013.
// 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 <mpllibs/metaparse/v1/return_.hpp>
#include <mpllibs/metaparse/v1/is_error.hpp>
#include <mpllibs/metaparse/v1/get_result.hpp>
#include <mpllibs/metaparse/v1/get_remaining.hpp>
#include <mpllibs/metaparse/v1/get_position.hpp>

#include <boost/mpl/deque.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/apply_wrap.hpp>
#include <boost/mpl/push_back.hpp>

namespace mpllibs
{
  namespace metaparse
  {
    namespace v1
    {
      namespace impl
      {
        template <int N, class P, class Accum>
        struct iterate_impl;
      }
    }
  }
}

#endif

