mirror of
https://github.com/vdemydiuk/mtapi.git
synced 2026-08-22 15:18:12 +00:00
Added thirdparty: boost library
This commit is contained in:
+319
@@ -0,0 +1,319 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
Copyright (c) 2002 Raghavendra Satish
|
||||
Copyright (c) 2002 Jeff Westfahl
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_LOOPS_HPP)
|
||||
#define BOOST_SPIRIT_LOOPS_HPP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/parser.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/composite.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// fixed_loop class
|
||||
//
|
||||
// This class takes care of the construct:
|
||||
//
|
||||
// repeat_p (exact) [p]
|
||||
//
|
||||
// where 'p' is a parser and 'exact' is the number of times to
|
||||
// repeat. The parser iterates over the input exactly 'exact' times.
|
||||
// The parse function fails if the parser does not match the input
|
||||
// exactly 'exact' times.
|
||||
//
|
||||
// This class is parametizable and can accept constant arguments
|
||||
// (e.g. repeat_p (5) [p]) as well as references to variables (e.g.
|
||||
// repeat_p (ref (n)) [p]).
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename ParserT, typename ExactT>
|
||||
class fixed_loop
|
||||
: public unary<ParserT, parser <fixed_loop <ParserT, ExactT> > >
|
||||
{
|
||||
public:
|
||||
|
||||
typedef fixed_loop<ParserT, ExactT> self_t;
|
||||
typedef unary<ParserT, parser<self_t> > base_t;
|
||||
|
||||
fixed_loop (ParserT const & subject_, ExactT const & exact)
|
||||
: base_t(subject_), m_exact(exact) {}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result <self_t, ScannerT>::type
|
||||
parse (ScannerT const & scan) const
|
||||
{
|
||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
||||
result_t hit = scan.empty_match();
|
||||
std::size_t n = m_exact;
|
||||
|
||||
for (std::size_t i = 0; i < n; ++i)
|
||||
{
|
||||
if (result_t next = this->subject().parse(scan))
|
||||
{
|
||||
scan.concat_match(hit, next);
|
||||
}
|
||||
else
|
||||
{
|
||||
return scan.no_match();
|
||||
}
|
||||
}
|
||||
|
||||
return hit;
|
||||
}
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename match_result<ScannerT, nil_t>::type type;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
ExactT m_exact;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// finite_loop class
|
||||
//
|
||||
// This class takes care of the construct:
|
||||
//
|
||||
// repeat_p (min, max) [p]
|
||||
//
|
||||
// where 'p' is a parser, 'min' and 'max' specifies the minimum and
|
||||
// maximum iterations over 'p'. The parser iterates over the input
|
||||
// at least 'min' times and at most 'max' times. The parse function
|
||||
// fails if the parser does not match the input at least 'min' times
|
||||
// and at most 'max' times.
|
||||
//
|
||||
// This class is parametizable and can accept constant arguments
|
||||
// (e.g. repeat_p (5, 10) [p]) as well as references to variables
|
||||
// (e.g. repeat_p (ref (n1), ref (n2)) [p]).
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename ParserT, typename MinT, typename MaxT>
|
||||
class finite_loop
|
||||
: public unary<ParserT, parser<finite_loop<ParserT, MinT, MaxT> > >
|
||||
{
|
||||
public:
|
||||
|
||||
typedef finite_loop <ParserT, MinT, MaxT> self_t;
|
||||
typedef unary<ParserT, parser<self_t> > base_t;
|
||||
|
||||
finite_loop (ParserT const & subject_, MinT const & min, MaxT const & max)
|
||||
: base_t(subject_), m_min(min), m_max(max) {}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result <self_t, ScannerT>::type
|
||||
parse(ScannerT const & scan) const
|
||||
{
|
||||
BOOST_SPIRIT_ASSERT(m_min <= m_max);
|
||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
||||
result_t hit = scan.empty_match();
|
||||
|
||||
std::size_t n1 = m_min;
|
||||
std::size_t n2 = m_max;
|
||||
|
||||
for (std::size_t i = 0; i < n2; ++i)
|
||||
{
|
||||
typename ScannerT::iterator_t save = scan.first;
|
||||
result_t next = this->subject().parse(scan);
|
||||
|
||||
if (!next)
|
||||
{
|
||||
if (i >= n1)
|
||||
{
|
||||
scan.first = save;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
return scan.no_match();
|
||||
}
|
||||
}
|
||||
|
||||
scan.concat_match(hit, next);
|
||||
}
|
||||
|
||||
return hit;
|
||||
}
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename match_result<ScannerT, nil_t>::type type;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
MinT m_min;
|
||||
MaxT m_max;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// infinite_loop class
|
||||
//
|
||||
// This class takes care of the construct:
|
||||
//
|
||||
// repeat_p (min, more) [p]
|
||||
//
|
||||
// where 'p' is a parser, 'min' is the minimum iteration over 'p'
|
||||
// and more specifies that the iteration should proceed
|
||||
// indefinitely. The parser iterates over the input at least 'min'
|
||||
// times and continues indefinitely until 'p' fails or all of the
|
||||
// input is parsed. The parse function fails if the parser does not
|
||||
// match the input at least 'min' times.
|
||||
//
|
||||
// This class is parametizable and can accept constant arguments
|
||||
// (e.g. repeat_p (5, more) [p]) as well as references to variables
|
||||
// (e.g. repeat_p (ref (n), more) [p]).
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct more_t {};
|
||||
more_t const more = more_t ();
|
||||
|
||||
template <typename ParserT, typename MinT>
|
||||
class infinite_loop
|
||||
: public unary<ParserT, parser<infinite_loop<ParserT, MinT> > >
|
||||
{
|
||||
public:
|
||||
|
||||
typedef infinite_loop <ParserT, MinT> self_t;
|
||||
typedef unary<ParserT, parser<self_t> > base_t;
|
||||
|
||||
infinite_loop (
|
||||
ParserT const& subject_,
|
||||
MinT const& min,
|
||||
more_t const&
|
||||
)
|
||||
: base_t(subject_), m_min(min) {}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result <self_t, ScannerT>::type
|
||||
parse(ScannerT const & scan) const
|
||||
{
|
||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
||||
result_t hit = scan.empty_match();
|
||||
std::size_t n = m_min;
|
||||
|
||||
for (std::size_t i = 0; ; ++i)
|
||||
{
|
||||
typename ScannerT::iterator_t save = scan.first;
|
||||
result_t next = this->subject().parse(scan);
|
||||
|
||||
if (!next)
|
||||
{
|
||||
if (i >= n)
|
||||
{
|
||||
scan.first = save;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
return scan.no_match();
|
||||
}
|
||||
}
|
||||
|
||||
scan.concat_match(hit, next);
|
||||
}
|
||||
|
||||
return hit;
|
||||
}
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename match_result<ScannerT, nil_t>::type type;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
MinT m_min;
|
||||
};
|
||||
|
||||
template <typename ExactT>
|
||||
struct fixed_loop_gen
|
||||
{
|
||||
fixed_loop_gen (ExactT const & exact)
|
||||
: m_exact (exact) {}
|
||||
|
||||
template <typename ParserT>
|
||||
fixed_loop <ParserT, ExactT>
|
||||
operator[](parser <ParserT> const & subject_) const
|
||||
{
|
||||
return fixed_loop <ParserT, ExactT> (subject_.derived (), m_exact);
|
||||
}
|
||||
|
||||
ExactT m_exact;
|
||||
};
|
||||
|
||||
namespace impl {
|
||||
|
||||
template <typename ParserT, typename MinT, typename MaxT>
|
||||
struct loop_traits
|
||||
{
|
||||
typedef typename mpl::if_<
|
||||
boost::is_same<MaxT, more_t>,
|
||||
infinite_loop<ParserT, MinT>,
|
||||
finite_loop<ParserT, MinT, MaxT>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
} // namespace impl
|
||||
|
||||
template <typename MinT, typename MaxT>
|
||||
struct nonfixed_loop_gen
|
||||
{
|
||||
nonfixed_loop_gen (MinT min, MaxT max)
|
||||
: m_min (min), m_max (max) {}
|
||||
|
||||
template <typename ParserT>
|
||||
typename impl::loop_traits<ParserT, MinT, MaxT>::type
|
||||
operator[](parser <ParserT> const & subject_) const
|
||||
{
|
||||
typedef typename impl::loop_traits<ParserT, MinT, MaxT>::type ret_t;
|
||||
return ret_t(
|
||||
subject_.derived(),
|
||||
m_min,
|
||||
m_max);
|
||||
}
|
||||
|
||||
MinT m_min;
|
||||
MaxT m_max;
|
||||
};
|
||||
|
||||
template <typename ExactT>
|
||||
fixed_loop_gen <ExactT>
|
||||
repeat_p(ExactT const & exact)
|
||||
{
|
||||
return fixed_loop_gen <ExactT> (exact);
|
||||
}
|
||||
|
||||
template <typename MinT, typename MaxT>
|
||||
nonfixed_loop_gen <MinT, MaxT>
|
||||
repeat_p(MinT const & min, MaxT const & max)
|
||||
{
|
||||
return nonfixed_loop_gen <MinT, MaxT> (min, max);
|
||||
}
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif // #if !defined(BOOST_SPIRIT_LOOPS_HPP)
|
||||
Reference in New Issue
Block a user