Imported existing code

This commit is contained in:
Hazim Gazov
2010-04-02 02:48:44 -03:00
parent 48fbc5ae91
commit 7a86d01598
13996 changed files with 2468699 additions and 0 deletions

View File

@@ -0,0 +1,369 @@
/*=============================================================================
Copyright (c) 2001-2007 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_CHAR_APR_16_2006_1051AM)
#define BOOST_SPIRIT_CHAR_APR_16_2006_1051AM
#include <boost/spirit/home/qi/char/char_parser.hpp>
#include <boost/spirit/home/qi/char/detail/get_char.hpp>
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/fusion/include/value_at.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/spirit/home/support/modifier.hpp>
#include <boost/spirit/home/support/char_class.hpp>
#include <boost/spirit/home/support/detail/to_narrow.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/foreach.hpp>
#include <boost/mpl/print.hpp>
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
// parse any character
///////////////////////////////////////////////////////////////////////////
template <typename Char>
struct any_char : char_parser<any_char<Char>, Char>
{
template <typename Component, typename CharParam, typename Context>
static bool test(Component const&, CharParam, Context&)
{
return true;
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return "any-char";
}
};
///////////////////////////////////////////////////////////////////////////
// parse a single character
///////////////////////////////////////////////////////////////////////////
template <typename Char>
struct literal_char : char_parser<literal_char<Char>, Char>
{
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef unused_type type; // literal parsers have no attribute
};
template <typename Component, typename CharParam, typename Context>
static bool test(Component const& component, CharParam ch, Context&)
{
return detail::get_char(fusion::at_c<0>(component.elements)) == ch;
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return std::string("'")
+ spirit::detail::to_narrow_char(
detail::get_char(fusion::at_c<0>(component.elements)))
+ '\'';
}
};
///////////////////////////////////////////////////////////////////////////
// parse a character set
///////////////////////////////////////////////////////////////////////////
template <typename Char>
struct char_set : char_parser<char_set<Char>, Char>
{
template <typename Component, typename CharParam, typename Context>
static bool test(Component const& component, CharParam ch, Context&)
{
return component.ptr->test(ch);
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return "char-set";
}
};
///////////////////////////////////////////////////////////////////////////
// parse a lazy character
///////////////////////////////////////////////////////////////////////////
struct lazy_char : char_parser<lazy_char>
{
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef typename
result_of::subject<Component>::type
subject_type;
typedef typename
remove_reference<
typename boost::result_of<subject_type(unused_type, Context)>::type
>::type
type;
};
template <typename Component, typename CharParam, typename Context>
static bool test(Component const& component, CharParam ch, Context& context)
{
return fusion::at_c<0>(component.elements)(unused, context) == ch;
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return std::string("'")
+ spirit::detail::to_narrow_char(
fusion::at_c<0>(component.elements)(unused, ctx))
+ '\'';
}
};
///////////////////////////////////////////////////////////////////////////
// parse a character range
///////////////////////////////////////////////////////////////////////////
template <typename Char>
struct char_range : char_parser<char_range<Char>, Char>
{
template <typename Component, typename CharParam, typename Context>
static bool test(Component const& component, CharParam ch, Context&)
{
return
!(ch < fusion::at_c<0>(component.elements)) &&
!(fusion::at_c<1>(component.elements) < ch);
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
std::string result;
result += std::string("'") + fusion::at_c<0>(component.elements) + '\'';
result += "...";
result += std::string("'") + fusion::at_c<1>(component.elements) + '\'';
return result;
}
};
///////////////////////////////////////////////////////////////////////////
// parse a lazy character range
///////////////////////////////////////////////////////////////////////////
struct lazy_char_range : char_parser<lazy_char_range>
{
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef typename
result_of::subject<Component>::type
subject_type;
typedef typename
remove_reference<
typename boost::result_of<subject_type(unused_type, Context)>::type
>::type
type;
};
template <typename Component, typename CharParam, typename Context>
static bool test(Component const& component, CharParam ch, Context& context)
{
return
!(ch < fusion::at_c<0>(component.elements)(unused, context)) &&
!(fusion::at_c<1>(component.elements)(unused, context) < ch);
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return "char-range";
}
};
///////////////////////////////////////////////////////////////////////////
// no_case literal_char version
///////////////////////////////////////////////////////////////////////////
template <typename Char>
struct no_case_literal_char : char_parser<no_case_literal_char<Char>, Char>
{
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef unused_type type; // literal parsers have no attribute
};
template <typename Component, typename CharParam, typename Context>
static bool test(Component const& component, CharParam ch, Context&)
{
return detail::get_char(fusion::at_c<0>(component.elements)) == ch
|| detail::get_char(fusion::at_c<1>(component.elements)) == ch
;
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
std::string result;
result += std::string("'")
+ spirit::detail::to_narrow_char(
detail::get_char(fusion::at_c<0>(component.elements))) + '\'';
result += " or ";
result += std::string("'") +
spirit::detail::to_narrow_char(
detail::get_char(fusion::at_c<1>(component.elements))) + '\'';
return result;
}
};
///////////////////////////////////////////////////////////////////////////
// no_case char_range version
///////////////////////////////////////////////////////////////////////////
template <typename Char>
struct no_case_char_range : char_parser<no_case_char_range<Char>, Char>
{
template <typename Component, typename CharParam, typename Context>
static bool test(Component const& component, CharParam ch, Context&)
{
return
(!(ch < fusion::at_c<0>(component.elements)) &&
!(fusion::at_c<1>(component.elements) < ch))
|| (!(ch < fusion::at_c<2>(component.elements)) &&
!(fusion::at_c<3>(component.elements) < ch))
;
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
std::string result;
result += std::string("'") + fusion::at_c<0>(component.elements) + '\'';
result += "...";
result += std::string("'") + fusion::at_c<1>(component.elements) + '\'';
result += " or ";
result += std::string("'") + fusion::at_c<2>(component.elements) + '\'';
result += "...";
result += std::string("'") + fusion::at_c<3>(component.elements) + '\'';
return result;
}
};
template <typename Char, typename Elements>
struct char_set_component;
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// char_set_component generator
///////////////////////////////////////////////////////////////////////////
template <typename Char, typename Elements, typename Modifier>
struct make_component<qi::domain, qi::char_set<Char>, Elements, Modifier
, typename disable_if<
is_member_of_modifier<Modifier, spirit::char_class::no_case_base_tag>
>::type
> : mpl::identity<qi::char_set_component<Char, Elements> >
{
static qi::char_set_component<Char, Elements>
call(Elements const& elements)
{
return qi::char_set_component<Char, Elements>(
fusion::at_c<0>(elements));
}
};
///////////////////////////////////////////////////////////////////////////
// no_case char_set_component generator
///////////////////////////////////////////////////////////////////////////
template <
typename Domain, typename Elements, typename Modifier, typename Char
>
struct make_modified_component<
Domain, qi::char_set<Char>, Elements, Modifier
, typename enable_if<
is_member_of_modifier<Modifier, spirit::char_class::no_case_base_tag>
>::type
>
{
typedef qi::char_set_component<Char, Elements> type;
typedef typename Modifier::char_set char_set;
static type
call(Elements const& elements)
{
return qi::char_set_component<Char, Elements>(
fusion::at_c<0>(elements), char_set());
}
};
///////////////////////////////////////////////////////////////////////////
// no_case_literal_char generator
///////////////////////////////////////////////////////////////////////////
template <
typename Domain, typename Elements, typename Modifier, typename Char
>
struct make_modified_component<
Domain, qi::literal_char<Char>, Elements, Modifier
, typename enable_if<
is_member_of_modifier<Modifier, spirit::char_class::no_case_base_tag>
>::type
>
{
typedef fusion::vector<Char, Char> vector_type;
typedef
component<qi::domain, qi::no_case_literal_char<Char>, vector_type>
type;
static type
call(Elements const& elements)
{
typedef typename Modifier::char_set char_set;
Char ch = qi::detail::get_char(fusion::at_c<0>(elements));
vector_type v(
char_set::tolower(ch)
, char_set::toupper(ch)
);
return type(v);
}
};
///////////////////////////////////////////////////////////////////////////
// no_case_char_range generator
///////////////////////////////////////////////////////////////////////////
template <
typename Domain, typename Elements, typename Modifier, typename Char
>
struct make_modified_component<
Domain, qi::char_range<Char>, Elements, Modifier
, typename enable_if<
is_member_of_modifier<Modifier, spirit::char_class::no_case_base_tag>
>::type
>
{
typedef fusion::vector<Char, Char, Char, Char> vector_type;
typedef
component<qi::domain, qi::no_case_char_range<Char>, vector_type>
type;
static type
call(Elements const& elements)
{
typedef typename Modifier::char_set char_set;
Char first = fusion::at_c<0>(elements);
Char last = fusion::at_c<1>(elements);
vector_type v(
char_set::tolower(first)
, char_set::tolower(last)
, char_set::toupper(first)
, char_set::toupper(last)
);
return type(v);
}
};
}}}
#endif

View File

@@ -0,0 +1,93 @@
/*=============================================================================
Copyright (c) 2001-2007 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_CHAR_CLASS_APR_16_2006_1051AM)
#define BOOST_SPIRIT_CHAR_CLASS_APR_16_2006_1051AM
#include <boost/spirit/home/qi/char/char_parser.hpp>
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/support/modifier.hpp>
#include <boost/spirit/home/support/iso8859_1.hpp>
#include <boost/spirit/home/support/ascii.hpp>
#include <boost/spirit/home/support/standard.hpp>
#include <boost/spirit/home/support/standard_wide.hpp>
#include <boost/fusion/include/cons.hpp>
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
// generic isxxx parser (for alnum, alpha, graph, etc.)
///////////////////////////////////////////////////////////////////////////
template <typename Tag>
struct char_class
: char_parser<char_class<Tag>, typename Tag::char_set::char_type>
{
typedef typename Tag::char_set char_set;
typedef typename Tag::char_class char_class_;
template <typename Component, typename CharParam, typename Context>
static bool test(Component const&, CharParam ch, Context&)
{
using spirit::char_class::classify;
return classify<char_set>::is(char_class_(), ch);
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
typedef spirit::char_class::what<char_set> what_;
return what_::is(char_class_());
}
};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// no_case char_class conversions
///////////////////////////////////////////////////////////////////////////
namespace detail
{
using spirit::char_class::key;
using spirit::char_class::lower_case_tag;
using spirit::char_class::upper_case_tag;
using spirit::char_class::tag::alpha;
template <typename Tag>
struct make_no_case_char_class :
mpl::identity<qi::char_class<Tag> > {};
template <typename CharSet>
struct make_no_case_char_class<lower_case_tag<CharSet> >
: mpl::identity<qi::char_class<key<CharSet, alpha> > > {};
template <typename CharSet>
struct make_no_case_char_class<upper_case_tag<CharSet> >
: mpl::identity<qi::char_class<key<CharSet, alpha> > > {};
}
template <
typename Domain, typename Elements, typename Modifier, typename Tag
>
struct make_modified_component<
Domain, qi::char_class<Tag>, Elements, Modifier
, typename enable_if<
is_member_of_modifier<Modifier, spirit::char_class::no_case_base_tag>
>::type
>
{
typedef typename detail::make_no_case_char_class<Tag>::type director;
typedef component<qi::domain, director, fusion::nil> type;
static type
call(Elements const&)
{
return type(fusion::nil());
}
};
}}}
#endif

View File

@@ -0,0 +1,82 @@
/*=============================================================================
Copyright (c) 2001-2007 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_CHAR_PARSER_APR_16_2006_0906AM)
#define BOOST_SPIRIT_CHAR_PARSER_APR_16_2006_0906AM
#include <string>
#include <boost/spirit/home/qi/skip.hpp>
#include <boost/spirit/home/qi/detail/assign_to.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/detail/iterator.hpp> // for boost::detail::iterator_traits
namespace boost { namespace spirit { namespace qi
{
template <typename Derived, typename Char = unused_type>
struct char_parser
{
typedef Char char_type;
// if Char is unused_type, Derived must supply its own attribute metafunction
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef Char type;
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& component
, Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr)
{
qi::skip(first, last, skipper);
if (first != last && Derived::test(component, *first, context))
{
qi::detail::assign_to(*first, attr);
++first;
return true;
}
return false;
}
// char_parser subclasses are required to
// implement test:
template <typename Component, typename CharParam, typename Context>
bool test(Component const& component, CharParam ch, Context& context);
};
template <typename Positive>
struct negated_char_parser :
char_parser<
negated_char_parser<Positive>, typename Positive::director::char_type
>
{
template <typename Component, typename CharParam, typename Context>
static bool test(Component const& component, CharParam ch, Context& context)
{
return !Positive::director::test(
fusion::at_c<0>(component.elements), ch, context);
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return std::string("not ")
+ Positive::director::what(fusion::at_c<0>(component.elements), ctx);
}
};
}}}
#endif

View File

@@ -0,0 +1,244 @@
/*=============================================================================
Copyright (c) 2001-2008 Joel de Guzman
Copyright (c) 2001-2003 Daniel Nuffer
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)
=============================================================================*/
#ifndef BOOST_SPIRIT_BASIC_CHSET_APRIL_17_2008
#define BOOST_SPIRIT_BASIC_CHSET_APRIL_17_2008
///////////////////////////////////////////////////////////////////////////////
#include <bitset>
#include <boost/spirit/home/qi/char/detail/range_run.hpp>
namespace boost { namespace spirit { namespace qi { namespace detail
{
///////////////////////////////////////////////////////////////////////////
//
// basic_chset: basic character set implementation using range_run
//
///////////////////////////////////////////////////////////////////////////
template <typename Char>
struct basic_chset
{
basic_chset() {}
basic_chset(basic_chset const& arg_)
: rr(arg_.rr) {}
bool
test(Char v) const
{
return rr.test(v);
}
void
set(Char from, Char to)
{
rr.set(range<Char>(from, to));
}
void
set(Char c)
{
rr.set(range<Char>(c, c));
}
void
clear(Char from, Char to)
{
rr.clear(range<Char>(from, to));
}
void
clear(Char c)
{
rr.clear(range<Char>(c, c));
}
void
clear()
{
rr.clear();
}
void
inverse()
{
basic_chset inv;
inv.set(
(std::numeric_limits<Char>::min)(),
(std::numeric_limits<Char>::max)()
);
inv -= *this;
swap(inv);
}
void
swap(basic_chset& x)
{
rr.swap(x.rr);
}
basic_chset&
operator|=(basic_chset const& x)
{
typedef typename range_run<Char>::const_iterator const_iterator;
for (const_iterator iter = x.rr.begin(); iter != x.rr.end(); ++iter)
rr.set(*iter);
return *this;
}
basic_chset&
operator&=(basic_chset const& x)
{
basic_chset inv;
inv.set(
(std::numeric_limits<Char>::min)(),
(std::numeric_limits<Char>::max)()
);
inv -= x;
*this -= inv;
return *this;
}
basic_chset&
operator-=(basic_chset const& x)
{
typedef typename range_run<Char>::const_iterator const_iterator;
for (const_iterator iter = x.rr.begin(); iter != x.rr.end(); ++iter)
rr.clear(*iter);
return *this;
}
basic_chset&
operator^=(basic_chset const& x)
{
basic_chset bma = x;
bma -= *this;
*this -= x;
*this |= bma;
return *this;
}
private: range_run<Char> rr;
};
#if (CHAR_BIT == 8)
///////////////////////////////////////////////////////////////////////////
//
// basic_chset: specializations for 8 bit chars using std::bitset
//
///////////////////////////////////////////////////////////////////////////
template <typename Char>
struct basic_chset_8bit
{
basic_chset_8bit() {}
basic_chset_8bit(basic_chset_8bit const& arg_)
: bset(arg_.bset) {}
bool
test(Char v) const
{
return bset.test((unsigned char)v);
}
void
set(Char from, Char to)
{
for (int i = from; i <= to; ++i)
bset.set((unsigned char)i);
}
void
set(Char c)
{
bset.set((unsigned char)c);
}
void
clear(Char from, Char to)
{
for (int i = from; i <= to; ++i)
bset.reset((unsigned char)i);
}
void
clear(Char c)
{
bset.reset((unsigned char)c);
}
void
clear()
{
bset.reset();
}
void
inverse()
{
bset.flip();
}
void
swap(basic_chset_8bit& x)
{
std::swap(bset, x.bset);
}
basic_chset_8bit&
operator|=(basic_chset_8bit const& x)
{
bset |= x.bset;
return *this;
}
basic_chset_8bit&
operator&=(basic_chset_8bit const& x)
{
bset &= x.bset;
return *this;
}
basic_chset_8bit&
operator-=(basic_chset_8bit const& x)
{
bset &= ~x.bset;
return *this;
}
basic_chset_8bit&
operator^=(basic_chset_8bit const& x)
{
bset ^= x.bset;
return *this;
}
private: std::bitset<256> bset;
};
/////////////////////////////////
template <>
struct basic_chset<char>
: basic_chset_8bit<char> {};
/////////////////////////////////
template <>
struct basic_chset<signed char>
: basic_chset_8bit<signed char> {};
/////////////////////////////////
template <>
struct basic_chset<unsigned char>
: basic_chset_8bit<unsigned char> {};
#endif // #if (CHAR_BIT == 8)
}}}}
#endif

View File

@@ -0,0 +1,36 @@
/*=============================================================================
Copyright (c) 2001-2007 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_GET_CHAR_APR_20_2008_0618_PM)
#define BOOST_SPIRIT_GET_CHAR_APR_20_2008_0618_PM
#include <string>
namespace boost { namespace spirit { namespace qi { namespace detail
{
// utility to get the (first) character from a primitive char,
// a null terminated string and a std::basic_string
template <typename Char>
static Char get_char(Char ch)
{
return ch;
}
template <typename Char>
static Char get_char(Char const* str)
{
return *str;
}
template <typename Char>
static Char get_char(std::basic_string<Char> const& str)
{
return str[0];
}
}}}}
#endif

View File

@@ -0,0 +1,35 @@
/*=============================================================================
Copyright (c) 2001-2007 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_RANGE_MAY_16_2006_0720_PM)
#define BOOST_SPIRIT_RANGE_MAY_16_2006_0720_PM
namespace boost { namespace spirit { namespace qi { namespace detail
{
///////////////////////////////////////////////////////////////////////////
// A closed range (first, last)
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct range
{
typedef T value_type;
range()
: first(), last()
{
}
range(T first, T last)
: first(first), last(last)
{
}
T first;
T last;
};
}}}}
#endif

View File

@@ -0,0 +1,94 @@
/*=============================================================================
Copyright (c) 2001-2007 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_RANGE_FUNCTIONS_MAY_16_2006_0720_PM)
#define BOOST_SPIRIT_RANGE_FUNCTIONS_MAY_16_2006_0720_PM
#include <boost/integer_traits.hpp>
namespace boost { namespace spirit { namespace qi { namespace detail
{
template <typename Range>
inline bool
is_valid(Range const& range)
{
// test for valid ranges
return range.first <= range.last;
}
template <typename Range>
inline bool
includes(Range const& range, Range const& other)
{
// see if two ranges intersect
return (range.first <= other.first) && (range.last >= other.last);
}
template <typename Range>
inline bool
includes(Range const& range, typename Range::value_type val)
{
// see if val is in range
return (range.first <= val) && (range.last >= val);
}
template <typename Range>
inline bool
can_merge(Range const& range, Range const& other)
{
// see if a 'range' overlaps, or is adjacent to
// another range 'other', so we can merge them
typedef typename Range::value_type value_type;
typedef integer_traits<value_type> integer_traits;
value_type decr_first =
range.first == integer_traits::const_min
? range.first : range.first-1;
value_type incr_last =
range.last == integer_traits::const_max
? range.last : range.last+1;
return (decr_first <= other.last) && (incr_last >= other.first);
}
template <typename Range>
inline void
merge(Range& result, Range const& other)
{
// merge two ranges
if (result.first > other.first)
result.first = other.first;
if (result.last < other.last)
result.last = other.last;
}
template <typename Range>
struct range_compare
{
// compare functor with a value or another range
typedef typename Range::value_type value_type;
bool operator()(Range const& x, const value_type y) const
{
return x.first < y;
}
bool operator()(value_type const x, Range const& y) const
{
return x < y.first;
}
bool operator()(Range const& x, Range const& y) const
{
return x.first < y.first;
}
};
}}}}
#endif

View File

@@ -0,0 +1,52 @@
/*=============================================================================
Copyright (c) 2001-2007 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_RANGE_RUN_MAY_16_2006_0801_PM)
#define BOOST_SPIRIT_RANGE_RUN_MAY_16_2006_0801_PM
#include <boost/spirit/home/qi/char/detail/range.hpp>
#include <vector>
namespace boost { namespace spirit { namespace qi { namespace detail
{
///////////////////////////////////////////////////////////////////////////
// range_run
//
// An implementation of a sparse bit (boolean) set. The set uses
// a sorted vector of disjoint ranges. This class implements the
// bare minimum essentials from which the full range of set
// operators can be implemented. The set is constructed from
// ranges. Internally, adjacent or overlapping ranges are
// coalesced.
//
// range_runs are very space-economical in situations where there
// are lots of ranges and a few individual disjoint values.
// Searching is O(log n) where n is the number of ranges.
//
// { Low level interface }
///////////////////////////////////////////////////////////////////////////
template <typename Char>
class range_run
{
public:
typedef range<Char> range_type;
typedef std::vector<range_type> storage_type;
void swap(range_run& other);
bool test(Char v) const;
void set(range_type const& range);
void clear(range_type const& range);
void clear();
private:
storage_type run;
};
}}}}
#include <boost/spirit/home/qi/char/detail/range_run_impl.hpp>
#endif

View File

@@ -0,0 +1,178 @@
/*=============================================================================
Copyright (c) 2001-2007 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_RANGE_RUN_MAY_16_2006_0807_PM)
#define BOOST_SPIRIT_RANGE_RUN_MAY_16_2006_0807_PM
#include <boost/spirit/home/qi/char/detail/range_functions.hpp>
#include <boost/assert.hpp>
#include <boost/integer_traits.hpp>
#include <algorithm>
namespace boost { namespace spirit { namespace qi { namespace detail
{
template <typename Run, typename Iterator, typename Range>
inline bool
try_merge(Run& run, Iterator iter, Range const& range)
{
// if *iter intersects with, or is adjacent to, 'range'...
if (can_merge(*iter, range))
{
typedef typename Range::value_type value_type;
typedef integer_traits<value_type> integer_traits;
// merge range and *iter
merge(*iter, range);
// collapse all subsequent ranges that can merge with *iter
Iterator i;
value_type last =
iter->last == integer_traits::const_max
? iter->last : iter->last+1;
for (i = iter+1; i != run.end() && last >= i->first; ++i)
{
iter->last = i->last;
}
// erase all ranges that were collapsed
run.erase(iter+1, i);
return true;
}
return false;
}
template <typename Char>
inline bool
range_run<Char>::test(Char val) const
{
if (run.empty())
return false;
// search the ranges for one that potentially includes val
typename storage_type::const_iterator iter =
std::upper_bound(
run.begin(), run.end(), val,
range_compare<range_type>()
);
// return true if *(iter-1) includes val
return iter != run.begin() && includes(*(--iter), val);
}
template <typename Char>
inline void
range_run<Char>::swap(range_run& other)
{
run.swap(other.run);
}
template <typename Char>
void
range_run<Char>::set(range_type const& range)
{
BOOST_ASSERT(is_valid(range));
if (run.empty())
{
// the vector is empty, insert 'range'
run.push_back(range);
return;
}
// search the ranges for one that potentially includes 'range'
typename storage_type::iterator iter =
std::upper_bound(
run.begin(), run.end(), range,
range_compare<range_type>()
);
if (iter != run.begin())
{
// if *(iter-1) includes 'range', return early
if (includes(*(iter-1), range))
{
return;
}
// if *(iter-1) can merge with 'range', merge them and return
if (try_merge(run, iter-1, range))
{
return;
}
}
// if *iter can merge with with 'range', merge them
if (iter == run.end() || !try_merge(run, iter, range))
{
// no overlap, insert 'range'
run.insert(iter, range);
}
}
template <typename Char>
void
range_run<Char>::clear(range_type const& range)
{
BOOST_ASSERT(is_valid(range));
if (!run.empty())
{
// search the ranges for one that potentially includes 'range'
typename storage_type::iterator iter =
std::upper_bound(
run.begin(), run.end(), range,
range_compare<range_type>()
);
typename storage_type::iterator left_iter;
// if *(iter-1) includes the 'range.first',
if ((iter != run.begin()) &&
includes(*(left_iter = (iter-1)), range.first))
{
// if the 'range' is in the middle,
if (left_iter->last > range.last)
{
// break it apart into two ranges (punch a hole)
Char save_last = left_iter->last;
left_iter->last = range.first-1;
run.insert(iter, range_type(range.last+1, save_last));
return;
}
else // if it is not in the middle,
{
// truncate it (clip its right)
left_iter->last = range.first-1;
}
}
// position i to the first range that 'range'
// does not intersect with
typename storage_type::iterator i = iter;
while (i != run.end() && includes(range, *i))
{
i++;
}
// if *i includes 'range.last', truncate it (clip its left)
if (i != run.end() && includes(*i, range.last))
{
i->first = range.last+1;
}
// cleanup... erase all subsequent ranges that the
// 'range' includes
run.erase(iter, i);
}
}
template <typename Char>
inline void
range_run<Char>::clear()
{
run.clear();
}
}}}}
#endif

View File

@@ -0,0 +1,396 @@
/*=============================================================================
Copyright (c) 2001-2007 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_META_GRAMMAR_FEB_02_2007_0925AM)
#define BOOST_SPIRIT_META_GRAMMAR_FEB_02_2007_0925AM
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/support/placeholders.hpp>
#include <boost/spirit/home/support/meta_grammar.hpp>
#include <boost/spirit/home/support/char_class.hpp>
#include <boost/spirit/home/qi/char/detail/basic_chset.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/shared_ptr.hpp>
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
// forwards
///////////////////////////////////////////////////////////////////////////
template <typename Char>
struct any_char;
template <typename Char>
struct literal_char;
struct lazy_char;
template <typename Char>
struct char_range;
struct lazy_char_range;
template <typename Positive>
struct negated_char_parser;
template <typename Tag>
struct char_class;
struct char_meta_grammar;
///////////////////////////////////////////////////////////////////////////
template <typename Expr, typename Enable>
struct is_valid_expr;
template <typename Expr, typename Enable>
struct expr_transform;
///////////////////////////////////////////////////////////////////////////
// get the director of an any_char
///////////////////////////////////////////////////////////////////////////
template <typename Tag>
struct extract_any_char_director;
template <>
struct extract_any_char_director<tag::char_>
{
typedef any_char<char> type;
};
template <>
struct extract_any_char_director<tag::wchar>
{
typedef any_char<wchar_t> type;
};
///////////////////////////////////////////////////////////////////////////
// get the director of a character literal type
///////////////////////////////////////////////////////////////////////////
template <typename Tag, typename T>
struct extract_literal_char_director;
template <typename T>
struct extract_literal_char_director<tag::char_, T>
{
typedef literal_char<T> type;
};
template <typename T>
struct extract_literal_char_director<tag::wchar, T>
{
typedef literal_char<wchar_t> type;
};
template <typename T>
struct extract_literal_char_director<tag::lit, T>
{
typedef literal_char<T> type;
};
template <typename T>
struct extract_literal_char_director<tag::wlit, T>
{
typedef literal_char<wchar_t> type;
};
///////////////////////////////////////////////////////////////////////////
// get the director of a character range type
///////////////////////////////////////////////////////////////////////////
template <typename Tag, typename T>
struct extract_char_range_director;
template <typename T>
struct extract_char_range_director<tag::char_, T>
{
typedef char_range<T> type;
};
template <typename T>
struct extract_char_range_director<tag::wchar, T>
{
typedef char_range<wchar_t> type;
};
///////////////////////////////////////////////////////////////////////////
// char parser meta-grammars
///////////////////////////////////////////////////////////////////////////
// literals: 'x', L'x'
struct basic_char_literal_meta_grammar
: proto::or_<
proto::terminal<char>
, proto::terminal<wchar_t>
>
{
};
// literals: 'x', L'x' and single char strings: "x", L"x"
struct single_char_literal_meta_grammar
: proto::or_<
// plain chars:
proto::terminal<char>
, proto::terminal<wchar_t>
// single char null terminates strings:
, proto::terminal<char[2]>
, proto::terminal<char(&)[2]>
, proto::terminal<wchar_t[2]>
, proto::terminal<wchar_t(&)[2]>
>
{
};
// literals: 'x', L'x'
struct char_literal_meta_grammar
: proto::or_<
meta_grammar::terminal_rule<
qi::domain, char, literal_char<char>
>
, meta_grammar::terminal_rule<
qi::domain, wchar_t, literal_char<wchar_t>
>
>
{
};
// literal strings: "hello" (defined in qi/string/meta_grammar.hpp)
struct basic_string_literal_meta_grammar;
// std::string(s) (defined in qi/string/meta_grammar.hpp)
struct basic_std_string_meta_grammar;
template <typename T>
struct extract_char; // (defined in qi/string/metagrammar.hpp)
template <typename Tag, typename T>
struct extract_chset_director;
template <typename T>
struct extract_chset_director<tag::char_, T>
{
typedef typename extract_char<T>::type char_type;
typedef char_set<char_type> type;
};
template <typename T>
struct extract_chset_director<tag::wchar, T>
{
typedef typename extract_char<T>::type char_type;
typedef char_set<char_type> type;
};
template <typename Char, typename Elements>
struct char_set_component
{
typedef qi::domain domain;
typedef char_set<Char> director;
typedef Elements elements_type;
char_set_component(Char const* definition)
: ptr(new detail::basic_chset<Char>())
{
Char ch = *definition++;
while (ch)
{
Char next = *definition++;
if (next == '-')
{
next = *definition++;
if (next == 0)
{
ptr->set(ch);
ptr->set('-');
break;
}
ptr->set(ch, next);
}
else
{
ptr->set(ch);
}
ch = next;
}
}
template <typename CharSetClass> // no-case version
char_set_component(Char const* definition, CharSetClass)
: ptr(new detail::basic_chset<Char>())
{
Char ch = *definition++;
while (ch)
{
Char next = *definition++;
if (next == '-')
{
next = *definition++;
if (next == 0)
{
ptr->set(CharSetClass::tolower(ch));
ptr->set(CharSetClass::tolower('-'));
ptr->set(CharSetClass::toupper(ch));
ptr->set(CharSetClass::toupper('-'));
break;
}
ptr->set(CharSetClass::tolower(ch)
, CharSetClass::tolower(next));
ptr->set(CharSetClass::toupper(ch)
, CharSetClass::toupper(next));
}
else
{
ptr->set(CharSetClass::tolower(ch));
ptr->set(CharSetClass::toupper(ch));
}
ch = next;
}
}
boost::shared_ptr<detail::basic_chset<Char> > ptr;
};
// char_, char_('x'), char_("x"), char_(f), char_('x', 'z'),
// char_(L'x'), char_(L'x', L'z'),
// wchar, wchar('x'), wchar("x"), wchar('x', 'z'),
// wchar(L'x'), wchar(L'x', L'z')
// char_("a-z"), wchar("a-z")
// [w]lit('x'), [w]lit(L'x')
struct char_meta_grammar1
: proto::or_<
// char_, wchar --> any_char
meta_grammar::compose_empty<
proto::if_<
is_char_tag<proto::_child, qi::domain>()
>
, qi::domain
, mpl::identity<extract_any_char_director<mpl::_> >
>
// char_('x'), wchar(L'x'), char_("x"), wchar(L"x")--> literal_char
, meta_grammar::compose_function1_eval<
proto::function<
proto::if_<
is_char_tag<proto::_child, qi::domain>()
>
, single_char_literal_meta_grammar
>
, qi::domain
, mpl::identity<extract_literal_char_director<mpl::_, mpl::_> >
>
// lit("x"), wlit(L"x") --> literal_char
, meta_grammar::compose_function1_eval<
proto::function<
proto::if_<
is_lit_tag<proto::_child, qi::domain>()
>
, basic_char_literal_meta_grammar
>
, qi::domain
, mpl::identity<extract_literal_char_director<mpl::_, mpl::_> >
>
// char_("a-z"), char_(L"a-z"), wchar(L"a-z") --> char_set
, meta_grammar::compose_function1_eval<
proto::function<
proto::if_<
is_char_tag<proto::_child, qi::domain>()>
, proto::or_<basic_string_literal_meta_grammar, basic_std_string_meta_grammar>
>
, qi::domain
, mpl::identity<extract_chset_director<mpl::_, mpl::_> >
>
// char_(F()) --> lazy_char
, meta_grammar::function1_rule<
qi::domain
, tag::char_
, lazy_char
>
// char_('x', 'z'), wchar(L'x', L'z') --> char_range
, meta_grammar::compose_function2_eval<
proto::function<
proto::if_<
is_char_tag<proto::_child, qi::domain>()
>
, basic_char_literal_meta_grammar
, basic_char_literal_meta_grammar
>
, qi::domain
, mpl::identity<extract_char_range_director<mpl::_, mpl::_> >
>
// char_(F1(), F2()) --> lazy_char_range
, meta_grammar::function2_rule<
qi::domain
, tag::char_
, lazy_char_range
>
>
{
};
// char_classes: alnum, alpha, cntrl, ... etc.
struct char_class_meta_grammar
: proto::or_<
// alnum, alpha, cntrl, ... etc.
meta_grammar::compose_empty<
proto::terminal<spirit::char_class::key<proto::_, proto::_> >
, qi::domain
, char_class<mpl::_>
>
, meta_grammar::compose_empty<
proto::terminal<spirit::char_class::lower_case_tag<proto::_> >
, qi::domain
, char_class<mpl::_>
>
, meta_grammar::compose_empty<
proto::terminal<spirit::char_class::upper_case_tag<proto::_> >
, qi::domain
, char_class<mpl::_>
>
>
{};
// ~x (where x is a char_parser)
struct negated_char_meta_grammar
: meta_grammar::compose_single<
proto::unary_expr<
proto::tag::complement
, char_meta_grammar
>
, qi::domain
, negated_char_parser<mpl::_>
>
{
};
// main char_meta_grammar
struct char_meta_grammar
: proto::or_<
char_meta_grammar1
, char_class_meta_grammar
, char_literal_meta_grammar
, negated_char_meta_grammar
>
{
};
///////////////////////////////////////////////////////////////////////////
// These specializations non-intrusively hooks into the RD meta-grammar.
// (see qi/meta_grammar.hpp)
///////////////////////////////////////////////////////////////////////////
template <typename Expr>
struct is_valid_expr<Expr
, typename enable_if<proto::matches<Expr, char_meta_grammar> >::type>
: mpl::true_
{
};
template <typename Expr>
struct expr_transform<Expr
, typename enable_if<proto::matches<Expr, char_meta_grammar> >::type>
: mpl::identity<char_meta_grammar>
{
};
}}}
#endif