Added boost header

This commit is contained in:
Christophe Riccio
2012-01-08 01:26:07 +00:00
parent 9c3faaca40
commit c7d752cdf8
8946 changed files with 1732316 additions and 0 deletions

View File

@@ -0,0 +1,174 @@
///////////////////////////////////////////////////////////////////////////////
// algorithm.hpp
//
// Copyright 2008 Eric Niebler. 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_XPRESSIVE_DETAIL_UTILITY_ALGORITHM_HPP_EAN_10_04_2005
#define BOOST_XPRESSIVE_DETAIL_UTILITY_ALGORITHM_HPP_EAN_10_04_2005
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include <string>
#include <climits>
#include <algorithm>
#include <boost/version.hpp>
#include <boost/range/end.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/size.hpp>
#include <boost/range/value_type.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/iterator/iterator_traits.hpp>
#include <boost/xpressive/detail/utility/ignore_unused.hpp>
namespace boost { namespace xpressive { namespace detail
{
///////////////////////////////////////////////////////////////////////////////
// any
//
template<typename InIter, typename Pred>
inline bool any(InIter begin, InIter end, Pred pred)
{
return end != std::find_if(begin, end, pred);
}
///////////////////////////////////////////////////////////////////////////////
// find_nth_if
//
template<typename FwdIter, typename Diff, typename Pred>
FwdIter find_nth_if(FwdIter begin, FwdIter end, Diff count, Pred pred)
{
for(; begin != end; ++begin)
{
if(pred(*begin) && 0 == count--)
{
return begin;
}
}
return end;
}
///////////////////////////////////////////////////////////////////////////////
// toi
//
template<typename InIter, typename Traits>
int toi(InIter &begin, InIter end, Traits const &tr, int radix = 10, int max = INT_MAX)
{
detail::ignore_unused(tr);
int i = 0, c = 0;
for(; begin != end && -1 != (c = tr.value(*begin, radix)); ++begin)
{
if(max < ((i *= radix) += c))
return i / radix;
}
return i;
}
///////////////////////////////////////////////////////////////////////////////
// advance_to
//
template<typename BidiIter, typename Diff>
inline bool advance_to_impl(BidiIter & iter, Diff diff, BidiIter end, std::bidirectional_iterator_tag)
{
for(; 0 < diff && iter != end; --diff)
++iter;
for(; 0 > diff && iter != end; ++diff)
--iter;
return 0 == diff;
}
template<typename RandIter, typename Diff>
inline bool advance_to_impl(RandIter & iter, Diff diff, RandIter end, std::random_access_iterator_tag)
{
if(0 < diff)
{
if((end - iter) < diff)
return false;
}
else if(0 > diff)
{
if((iter - end) < -diff)
return false;
}
iter += diff;
return true;
}
template<typename Iter, typename Diff>
inline bool advance_to(Iter & iter, Diff diff, Iter end)
{
return detail::advance_to_impl(iter, diff, end, typename iterator_category<Iter>::type());
}
///////////////////////////////////////////////////////////////////////////////
// range_data
//
template<typename T>
struct range_data
: range_value<T>
{};
template<typename T>
struct range_data<T *>
: remove_const<T>
{};
template<typename T> std::ptrdiff_t is_null_terminated(T const &) { return 0; }
#if BOOST_VERSION >= 103500
inline std::ptrdiff_t is_null_terminated(char const *) { return 1; }
#ifndef BOOST_XPRESSIVE_NO_WREGEX
inline std::ptrdiff_t is_null_terminated(wchar_t const *) { return 1; }
#endif
#endif
///////////////////////////////////////////////////////////////////////////////
// data_begin/data_end
//
template<typename Cont>
typename range_data<Cont>::type const *data_begin(Cont const &cont)
{
return &*boost::begin(cont);
}
template<typename Cont>
typename range_data<Cont>::type const *data_end(Cont const &cont)
{
return &*boost::begin(cont) + boost::size(cont) - is_null_terminated(cont);
}
template<typename Char, typename Traits, typename Alloc>
Char const *data_begin(std::basic_string<Char, Traits, Alloc> const &str)
{
return str.data();
}
template<typename Char, typename Traits, typename Alloc>
Char const *data_end(std::basic_string<Char, Traits, Alloc> const &str)
{
return str.data() + str.size();
}
template<typename Char>
Char const *data_begin(Char const *const &sz)
{
return sz;
}
template<typename Char>
Char const *data_end(Char const *const &sz)
{
Char const *tmp = sz;
for(; *tmp; ++tmp)
;
return tmp;
}
}}}
#endif

View File

@@ -0,0 +1,108 @@
///////////////////////////////////////////////////////////////////////////////
// any.hpp
//
// Copyright 2008 Eric Niebler. 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_XPRESSIVE_DETAIL_UTILITY_ANY_HPP_EAN_11_19_2005
#define BOOST_XPRESSIVE_DETAIL_UTILITY_ANY_HPP_EAN_11_19_2005
#include <boost/version.hpp>
#if BOOST_VERSION >= 103300
// In Boost 1.33+, we have a cons list in Fusion, so just include it.
# if BOOST_VERSION >= 103500
# include <boost/fusion/include/any.hpp> // Boost 1.35+ has Fusion2
# else
# include <boost/spirit/fusion/algorithm/any.hpp> // Fusion1
# endif
#else
# include <boost/spirit/fusion/sequence/begin.hpp>
# include <boost/spirit/fusion/sequence/end.hpp>
# include <boost/spirit/fusion/iterator/equal_to.hpp>
# include <boost/mpl/bool.hpp>
# include <boost/spirit/fusion/iterator/equal_to.hpp>
# include <boost/spirit/fusion/iterator/next.hpp>
# include <boost/spirit/fusion/iterator/deref.hpp>
namespace boost { namespace fusion
{
namespace detail
{
template <typename First, typename Last, typename F>
inline bool
any(First const&, Last const&, F const&, mpl::true_)
{
return false;
}
template <typename First, typename Last, typename F>
inline bool
any(First const& first, Last const& last, F const& f, mpl::false_)
{
if(f(*first))
return true;
return detail::any(fusion::next(first), last, f
, meta::equal_to<BOOST_DEDUCED_TYPENAME meta::next<First>::type, Last>());
}
}
namespace meta
{
template <typename Sequence, typename F>
struct any
{
typedef bool type;
};
}
namespace function
{
struct any
{
template <typename Sequence, typename F>
struct apply
{
typedef bool type;
};
template <typename Sequence, typename F>
inline bool
operator()(Sequence const& seq, F const& f) const
{
return detail::any(
fusion::begin(seq)
, fusion::end(seq)
, f
, meta::equal_to<
BOOST_DEDUCED_TYPENAME meta::begin<Sequence>::type
, BOOST_DEDUCED_TYPENAME meta::end<Sequence>::type>());
}
template <typename Sequence, typename F>
inline bool
operator()(Sequence& seq, F const& f) const
{
return detail::any(
fusion::begin(seq)
, fusion::end(seq)
, f
, meta::equal_to<
BOOST_DEDUCED_TYPENAME meta::begin<Sequence>::type
, BOOST_DEDUCED_TYPENAME meta::end<Sequence>::type>());
}
};
}
function::any const any = function::any();
}}
#endif
#endif

View File

@@ -0,0 +1,198 @@
///////////////////////////////////////////////////////////////////////////////
/// \file boyer_moore.hpp
/// Contains the boyer-moore implementation. Note: this is *not* a general-
/// purpose boyer-moore implementation. It truncates the search string at
/// 256 characters, but it is sufficient for the needs of xpressive.
//
// Copyright 2008 Eric Niebler. 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_XPRESSIVE_DETAIL_BOYER_MOORE_HPP_EAN_10_04_2005
#define BOOST_XPRESSIVE_DETAIL_BOYER_MOORE_HPP_EAN_10_04_2005
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
# pragma warning(push)
# pragma warning(disable : 4100) // unreferenced formal parameter
#endif
#include <climits> // for UCHAR_MAX
#include <cstddef> // for std::ptrdiff_t
#include <utility> // for std::max
#include <vector>
#include <boost/mpl/bool.hpp>
#include <boost/noncopyable.hpp>
#include <boost/iterator/iterator_traits.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/xpressive/detail/detail_fwd.hpp>
namespace boost { namespace xpressive { namespace detail
{
///////////////////////////////////////////////////////////////////////////////
// boyer_moore
//
template<typename BidiIter, typename Traits>
struct boyer_moore
: noncopyable
{
typedef typename iterator_value<BidiIter>::type char_type;
typedef Traits traits_type;
typedef has_fold_case<Traits> case_fold;
typedef typename Traits::string_type string_type;
// initialize the Boyer-Moore search data structure, using the
// search sub-sequence to prime the pump.
boyer_moore(char_type const *begin, char_type const *end, Traits const &tr, bool icase)
: begin_(begin)
, last_(begin)
, fold_()
, find_fun_(
icase
? (case_fold() ? &boyer_moore::find_nocase_fold_ : &boyer_moore::find_nocase_)
: &boyer_moore::find_
)
{
std::ptrdiff_t const uchar_max = UCHAR_MAX;
std::ptrdiff_t diff = std::distance(begin, end);
this->length_ = static_cast<unsigned char>((std::min)(diff, uchar_max));
std::fill_n(static_cast<unsigned char *>(this->offsets_), uchar_max + 1, this->length_);
--this->length_;
icase ? this->init_(tr, case_fold()) : this->init_(tr, mpl::false_());
}
BidiIter find(BidiIter begin, BidiIter end, Traits const &tr) const
{
return (this->*this->find_fun_)(begin, end, tr);
}
private:
void init_(Traits const &tr, mpl::false_)
{
for(unsigned char offset = this->length_; offset; --offset, ++this->last_)
{
this->offsets_[tr.hash(*this->last_)] = offset;
}
}
void init_(Traits const &tr, mpl::true_)
{
this->fold_.reserve(this->length_ + 1);
for(unsigned char offset = this->length_; offset; --offset, ++this->last_)
{
this->fold_.push_back(tr.fold_case(*this->last_));
for(typename string_type::const_iterator beg = this->fold_.back().begin(), end = this->fold_.back().end();
beg != end; ++beg)
{
this->offsets_[tr.hash(*beg)] = offset;
}
}
this->fold_.push_back(tr.fold_case(*this->last_));
}
// case-sensitive Boyer-Moore search
BidiIter find_(BidiIter begin, BidiIter end, Traits const &tr) const
{
typedef typename boost::iterator_difference<BidiIter>::type diff_type;
diff_type const endpos = std::distance(begin, end);
diff_type offset = static_cast<diff_type>(this->length_);
for(diff_type curpos = offset; curpos < endpos; curpos += offset)
{
std::advance(begin, offset);
char_type const *pat_tmp = this->last_;
BidiIter str_tmp = begin;
for(; tr.translate(*str_tmp) == *pat_tmp; --pat_tmp, --str_tmp)
{
if(pat_tmp == this->begin_)
{
return str_tmp;
}
}
offset = this->offsets_[tr.hash(tr.translate(*begin))];
}
return end;
}
// case-insensitive Boyer-Moore search
BidiIter find_nocase_(BidiIter begin, BidiIter end, Traits const &tr) const
{
typedef typename boost::iterator_difference<BidiIter>::type diff_type;
diff_type const endpos = std::distance(begin, end);
diff_type offset = static_cast<diff_type>(this->length_);
for(diff_type curpos = offset; curpos < endpos; curpos += offset)
{
std::advance(begin, offset);
char_type const *pat_tmp = this->last_;
BidiIter str_tmp = begin;
for(; tr.translate_nocase(*str_tmp) == *pat_tmp; --pat_tmp, --str_tmp)
{
if(pat_tmp == this->begin_)
{
return str_tmp;
}
}
offset = this->offsets_[tr.hash(tr.translate_nocase(*begin))];
}
return end;
}
// case-insensitive Boyer-Moore search with case-folding
BidiIter find_nocase_fold_(BidiIter begin, BidiIter end, Traits const &tr) const
{
typedef typename boost::iterator_difference<BidiIter>::type diff_type;
diff_type const endpos = std::distance(begin, end);
diff_type offset = static_cast<diff_type>(this->length_);
for(diff_type curpos = offset; curpos < endpos; curpos += offset)
{
std::advance(begin, offset);
string_type const *pat_tmp = &this->fold_.back();
BidiIter str_tmp = begin;
for(; pat_tmp->end() != std::find(pat_tmp->begin(), pat_tmp->end(), *str_tmp);
--pat_tmp, --str_tmp)
{
if(pat_tmp == &this->fold_.front())
{
return str_tmp;
}
}
offset = this->offsets_[tr.hash(*begin)];
}
return end;
}
private:
char_type const *begin_;
char_type const *last_;
std::vector<string_type> fold_;
BidiIter (boyer_moore::*const find_fun_)(BidiIter, BidiIter, Traits const &) const;
unsigned char length_;
unsigned char offsets_[UCHAR_MAX + 1];
};
}}} // namespace boost::xpressive::detail
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma warning(pop)
#endif
#endif

View File

@@ -0,0 +1,172 @@
/*=============================================================================
Copyright (c) 2001-2003 Joel de Guzman
Copyright (c) 2001-2003 Daniel Nuffer
http://spirit.sourceforge.net/
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef BOOST_XPRESSIVE_SPIRIT_BASIC_CHSET_HPP_EAN_10_04_2005
#define BOOST_XPRESSIVE_SPIRIT_BASIC_CHSET_HPP_EAN_10_04_2005
///////////////////////////////////////////////////////////////////////////////
#include <bitset>
#include <boost/mpl/bool.hpp>
#include <boost/xpressive/detail/utility/chset/range_run.ipp>
namespace boost { namespace xpressive { 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);
bool empty() const;
void set(Char from, Char to);
template<typename Traits>
void set(Char from, Char to, Traits const &tr);
void set(Char c);
template<typename Traits>
void set(Char c, Traits const &tr);
void clear(Char from, Char to);
template<typename Traits>
void clear(Char from, Char to, Traits const &tr);
void clear(Char c);
template<typename Traits>
void clear(Char c, Traits const &tr);
void clear();
template<typename Traits>
bool test(Char v, Traits const &tr, mpl::false_) const; // case-sensitive
template<typename Traits>
bool test(Char v, Traits const &tr, mpl::true_) const; // case-insensitive
void inverse();
void swap(basic_chset& x);
basic_chset &operator |=(basic_chset const &x);
basic_chset &operator &=(basic_chset const &x);
basic_chset &operator -=(basic_chset const &x);
basic_chset &operator ^=(basic_chset const &x);
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);
bool empty() const;
void set(Char from, Char to);
template<typename Traits>
void set(Char from, Char to, Traits const &tr);
void set(Char c);
template<typename Traits>
void set(Char c, Traits const &tr);
void clear(Char from, Char to);
template<typename Traits>
void clear(Char from, Char to, Traits const &tr);
void clear(Char c);
template<typename Traits>
void clear(Char c, Traits const &tr);
void clear();
template<typename Traits>
bool test(Char v, Traits const &tr, mpl::false_) const; // case-sensitive
template<typename Traits>
bool test(Char v, Traits const &tr, mpl::true_) const; // case-insensitive
void inverse();
void swap(basic_chset_8bit& x);
basic_chset_8bit &operator |=(basic_chset_8bit const &x);
basic_chset_8bit &operator &=(basic_chset_8bit const &x);
basic_chset_8bit &operator -=(basic_chset_8bit const &x);
basic_chset_8bit &operator ^=(basic_chset_8bit const &x);
std::bitset<256> const &base() const;
private:
std::bitset<256> bset_; // BUGBUG range-checking slows this down
};
/////////////////////////////////
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
///////////////////////////////////////////////////////////////////////////////
// is_narrow_char
template<typename Char>
struct is_narrow_char
: mpl::false_
{};
template<>
struct is_narrow_char<char>
: mpl::true_
{};
template<>
struct is_narrow_char<signed char>
: mpl::true_
{};
template<>
struct is_narrow_char<unsigned char>
: mpl::true_
{};
///////////////////////////////////////////////////////////////////////////////
// helpers
template<typename Char, typename Traits>
void set_char(basic_chset<Char> &chset, Char ch, Traits const &tr, bool icase);
template<typename Char, typename Traits>
void set_range(basic_chset<Char> &chset, Char from, Char to, Traits const &tr, bool icase);
template<typename Char, typename Traits>
void set_class(basic_chset<Char> &chset, typename Traits::char_class_type char_class, bool no, Traits const &tr);
}}} // namespace boost::xpressive::detail
#endif

View File

@@ -0,0 +1,409 @@
/*=============================================================================
Copyright (c) 2001-2003 Joel de Guzman
Copyright (c) 2001-2003 Daniel Nuffer
http://spirit.sourceforge.net/
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef BOOST_XPRESSIVE_SPIRIT_BASIC_CHSET_IPP
#define BOOST_XPRESSIVE_SPIRIT_BASIC_CHSET_IPP
///////////////////////////////////////////////////////////////////////////////
#include <bitset>
#include <boost/xpressive/detail/utility/chset/basic_chset.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace xpressive { namespace detail
{
///////////////////////////////////////////////////////////////////////////////
//
// basic_chset: character set implementation
//
///////////////////////////////////////////////////////////////////////////////
template<typename Char>
inline basic_chset<Char>::basic_chset()
{
}
//////////////////////////////////
template<typename Char>
inline basic_chset<Char>::basic_chset(basic_chset const &arg)
: rr_(arg.rr_)
{
}
//////////////////////////////////
template<typename Char>
inline bool basic_chset<Char>::empty() const
{
return this->rr_.empty();
}
//////////////////////////////////
template<typename Char>
template<typename Traits>
inline bool basic_chset<Char>::test(Char v, Traits const &, mpl::false_) const // case-sensitive
{
return this->rr_.test(v);
}
//////////////////////////////////
template<typename Char>
template<typename Traits>
inline bool basic_chset<Char>::test(Char v, Traits const &tr, mpl::true_) const // case-insensitive
{
return this->rr_.test(v, tr);
}
//////////////////////////////////
template<typename Char>
inline void basic_chset<Char>::set(Char from, Char to)
{
this->rr_.set(range<Char>(from, to));
}
//////////////////////////////////
template<typename Char>
template<typename Traits>
inline void basic_chset<Char>::set(Char from, Char to, Traits const &)
{
this->rr_.set(range<Char>(from, to));
}
//////////////////////////////////
template<typename Char>
inline void basic_chset<Char>::set(Char c)
{
this->rr_.set(range<Char>(c, c));
}
//////////////////////////////////
template<typename Char>
template<typename Traits>
inline void basic_chset<Char>::set(Char c, Traits const &)
{
this->rr_.set(range<Char>(c, c));
}
//////////////////////////////////
template<typename Char>
inline void basic_chset<Char>::clear(Char c)
{
this->rr_.clear(range<Char>(c, c));
}
//////////////////////////////////
template<typename Char>
template<typename Traits>
inline void basic_chset<Char>::clear(Char c, Traits const &)
{
this->rr_.clear(range<Char>(c, c));
}
//////////////////////////////////
template<typename Char>
inline void basic_chset<Char>::clear(Char from, Char to)
{
this->rr_.clear(range<Char>(from, to));
}
//////////////////////////////////
template<typename Char>
template<typename Traits>
inline void basic_chset<Char>::clear(Char from, Char to, Traits const &)
{
this->rr_.clear(range<Char>(from, to));
}
//////////////////////////////////
template<typename Char>
inline void basic_chset<Char>::clear()
{
this->rr_.clear();
}
/////////////////////////////////
template<typename Char>
inline void basic_chset<Char>::inverse()
{
// BUGBUG is this right? Does this handle icase correctly?
basic_chset<Char> inv;
inv.set((std::numeric_limits<Char>::min)(), (std::numeric_limits<Char>::max)());
inv -= *this;
this->swap(inv);
}
/////////////////////////////////
template<typename Char>
inline void basic_chset<Char>::swap(basic_chset<Char> &that)
{
this->rr_.swap(that.rr_);
}
/////////////////////////////////
template<typename Char>
inline basic_chset<Char> &
basic_chset<Char>::operator |=(basic_chset<Char> const &that)
{
typedef typename range_run<Char>::const_iterator const_iterator;
for(const_iterator iter = that.rr_.begin(); iter != that.rr_.end(); ++iter)
{
this->rr_.set(*iter);
}
return *this;
}
/////////////////////////////////
template<typename Char>
inline basic_chset<Char> &
basic_chset<Char>::operator &=(basic_chset<Char> const &that)
{
basic_chset<Char> inv;
inv.set((std::numeric_limits<Char>::min)(), (std::numeric_limits<Char>::max)());
inv -= that;
*this -= inv;
return *this;
}
/////////////////////////////////
template<typename Char>
inline basic_chset<Char> &
basic_chset<Char>::operator -=(basic_chset<Char> const &that)
{
typedef typename range_run<Char>::const_iterator const_iterator;
for(const_iterator iter = that.rr_.begin(); iter != that.rr_.end(); ++iter)
{
this->rr_.clear(*iter);
}
return *this;
}
/////////////////////////////////
template<typename Char>
inline basic_chset<Char> &
basic_chset<Char>::operator ^=(basic_chset<Char> const &that)
{
basic_chset bma = that;
bma -= *this;
*this -= that;
*this |= bma;
return *this;
}
#if(CHAR_BIT == 8)
///////////////////////////////////////////////////////////////////////////////
//
// basic_chset: specializations for 8 bit chars using std::bitset
//
///////////////////////////////////////////////////////////////////////////////
template<typename Char>
inline basic_chset_8bit<Char>::basic_chset_8bit()
{
}
/////////////////////////////////
template<typename Char>
inline basic_chset_8bit<Char>::basic_chset_8bit(basic_chset_8bit<Char> const &arg)
: bset_(arg.bset_)
{
}
/////////////////////////////////
template<typename Char>
inline bool basic_chset_8bit<Char>::empty() const
{
return !this->bset_.any();
}
/////////////////////////////////
template<typename Char>
template<typename Traits>
inline bool basic_chset_8bit<Char>::test(Char v, Traits const &, mpl::false_) const // case-sensitive
{
return this->bset_.test((unsigned char)v);
}
/////////////////////////////////
template<typename Char>
template<typename Traits>
inline bool basic_chset_8bit<Char>::test(Char v, Traits const &tr, mpl::true_) const // case-insensitive
{
return this->bset_.test((unsigned char)tr.translate_nocase(v));
}
/////////////////////////////////
template<typename Char>
inline void basic_chset_8bit<Char>::set(Char from, Char to)
{
for(int i = from; i <= to; ++i)
{
this->bset_.set((unsigned char)i);
}
}
/////////////////////////////////
template<typename Char>
template<typename Traits>
inline void basic_chset_8bit<Char>::set(Char from, Char to, Traits const &tr)
{
for(int i = from; i <= to; ++i)
{
this->bset_.set((unsigned char)tr.translate_nocase((Char)i));
}
}
/////////////////////////////////
template<typename Char>
inline void basic_chset_8bit<Char>::set(Char c)
{
this->bset_.set((unsigned char)c);
}
/////////////////////////////////
template<typename Char>
template<typename Traits>
inline void basic_chset_8bit<Char>::set(Char c, Traits const &tr)
{
this->bset_.set((unsigned char)tr.translate_nocase(c));
}
/////////////////////////////////
template<typename Char>
inline void basic_chset_8bit<Char>::clear(Char from, Char to)
{
for(int i = from; i <= to; ++i)
{
this->bset_.reset((unsigned char)i);
}
}
/////////////////////////////////
template<typename Char>
template<typename Traits>
inline void basic_chset_8bit<Char>::clear(Char from, Char to, Traits const &tr)
{
for(int i = from; i <= to; ++i)
{
this->bset_.reset((unsigned char)tr.translate_nocase((Char)i));
}
}
/////////////////////////////////
template<typename Char>
inline void basic_chset_8bit<Char>::clear(Char c)
{
this->bset_.reset((unsigned char)c);
}
/////////////////////////////////
template<typename Char>
template<typename Traits>
inline void basic_chset_8bit<Char>::clear(Char c, Traits const &tr)
{
this->bset_.reset((unsigned char)tr.tranlsate_nocase(c));
}
/////////////////////////////////
template<typename Char>
inline void basic_chset_8bit<Char>::clear()
{
this->bset_.reset();
}
/////////////////////////////////
template<typename Char>
inline void basic_chset_8bit<Char>::inverse()
{
this->bset_.flip();
}
/////////////////////////////////
template<typename Char>
inline void basic_chset_8bit<Char>::swap(basic_chset_8bit<Char> &that)
{
std::swap(this->bset_, that.bset_);
}
/////////////////////////////////
template<typename Char>
inline basic_chset_8bit<Char> &
basic_chset_8bit<Char>::operator |=(basic_chset_8bit<Char> const &that)
{
this->bset_ |= that.bset_;
return *this;
}
/////////////////////////////////
template<typename Char>
inline basic_chset_8bit<Char> &
basic_chset_8bit<Char>::operator &=(basic_chset_8bit<Char> const &that)
{
this->bset_ &= that.bset_;
return *this;
}
/////////////////////////////////
template<typename Char>
inline basic_chset_8bit<Char> &
basic_chset_8bit<Char>::operator -=(basic_chset_8bit<Char> const &that)
{
this->bset_ &= ~that.bset_;
return *this;
}
/////////////////////////////////
template<typename Char>
inline basic_chset_8bit<Char> &
basic_chset_8bit<Char>::operator ^=(basic_chset_8bit<Char> const &that)
{
this->bset_ ^= that.bset_;
return *this;
}
template<typename Char>
inline std::bitset<256> const &
basic_chset_8bit<Char>::base() const
{
return this->bset_;
}
#endif // if(CHAR_BIT == 8)
///////////////////////////////////////////////////////////////////////////////
// helpers
template<typename Char, typename Traits>
inline void set_char(basic_chset<Char> &chset, Char ch, Traits const &tr, bool icase)
{
icase ? chset.set(ch, tr) : chset.set(ch);
}
template<typename Char, typename Traits>
inline void set_range(basic_chset<Char> &chset, Char from, Char to, Traits const &tr, bool icase)
{
icase ? chset.set(from, to, tr) : chset.set(from, to);
}
template<typename Char, typename Traits>
inline void set_class(basic_chset<Char> &chset, typename Traits::char_class_type char_class, bool no, Traits const &tr)
{
BOOST_MPL_ASSERT_RELATION(1, ==, sizeof(Char));
for(std::size_t i = 0; i <= UCHAR_MAX; ++i)
{
typedef typename std::char_traits<Char>::int_type int_type;
Char ch = std::char_traits<Char>::to_char_type(static_cast<int_type>(i));
if(no != tr.isctype(ch, char_class))
{
chset.set(ch);
}
}
}
}}} // namespace boost::xpressive::detail
#endif

View File

@@ -0,0 +1,165 @@
///////////////////////////////////////////////////////////////////////////////
// chset.hpp
//
// Copyright 2008 Eric Niebler. 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_XPRESSIVE_DETAIL_CHSET_CHSET_HPP_EAN_10_04_2005
#define BOOST_XPRESSIVE_DETAIL_CHSET_CHSET_HPP_EAN_10_04_2005
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include <vector>
#include <boost/call_traits.hpp>
#include <boost/xpressive/detail/detail_fwd.hpp>
#include <boost/xpressive/detail/utility/algorithm.hpp>
#include <boost/xpressive/detail/utility/chset/basic_chset.ipp>
namespace boost { namespace xpressive { namespace detail
{
///////////////////////////////////////////////////////////////////////////////
// compound_charset
//
template<typename Traits>
struct compound_charset
: private basic_chset<typename Traits::char_type>
{
typedef typename Traits::char_type char_type;
typedef basic_chset<char_type> base_type;
typedef Traits traits_type;
typedef typename Traits::char_class_type char_class_type;
compound_charset()
: base_type()
, complement_(false)
, has_posix_(false)
, posix_yes_()
, posix_no_()
{
}
///////////////////////////////////////////////////////////////////////////////
// accessors
basic_chset<char_type> const &base() const
{
return *this;
}
bool is_inverted() const
{
return this->complement_;
}
char_class_type posix_yes() const
{
return this->posix_yes_;
}
std::vector<char_class_type> const &posix_no() const
{
return this->posix_no_;
}
///////////////////////////////////////////////////////////////////////////////
// complement
void inverse()
{
this->complement_ = !this->complement_;
}
///////////////////////////////////////////////////////////////////////////////
// set
void set_char(char_type ch, Traits const &tr, bool icase)
{
icase ? this->base_type::set(ch, tr) : this->base_type::set(ch);
}
void set_range(char_type from, char_type to, Traits const &tr, bool icase)
{
icase ? this->base_type::set(from, to, tr) : this->base_type::set(from, to);
}
void set_class(char_class_type const &m, bool no)
{
this->has_posix_ = true;
if(no)
{
this->posix_no_.push_back(m);
}
else
{
this->posix_yes_ |= m;
}
}
///////////////////////////////////////////////////////////////////////////////
// test
template<typename ICase>
bool test(char_type ch, Traits const &tr, ICase) const
{
return this->complement_ !=
(this->base_type::test(ch, tr, ICase()) ||
(this->has_posix_ && this->test_posix(ch, tr)));
}
private:
///////////////////////////////////////////////////////////////////////////////
// not_posix_pred
struct not_posix_pred
{
char_type ch_;
Traits const *traits_ptr_;
bool operator ()(typename call_traits<char_class_type>::param_type m) const
{
return !this->traits_ptr_->isctype(this->ch_, m);
}
};
///////////////////////////////////////////////////////////////////////////////
// test_posix
bool test_posix(char_type ch, Traits const &tr) const
{
not_posix_pred const pred = {ch, &tr};
return tr.isctype(ch, this->posix_yes_)
|| any(this->posix_no_.begin(), this->posix_no_.end(), pred);
}
bool complement_;
bool has_posix_;
char_class_type posix_yes_;
std::vector<char_class_type> posix_no_;
};
///////////////////////////////////////////////////////////////////////////////
// helpers
template<typename Char, typename Traits>
inline void set_char(compound_charset<Traits> &chset, Char ch, Traits const &tr, bool icase)
{
chset.set_char(ch, tr, icase);
}
template<typename Char, typename Traits>
inline void set_range(compound_charset<Traits> &chset, Char from, Char to, Traits const &tr, bool icase)
{
chset.set_range(from, to, tr, icase);
}
template<typename Traits>
inline void set_class(compound_charset<Traits> &chset, typename Traits::char_class_type char_class, bool no, Traits const &)
{
chset.set_class(char_class, no);
}
}}} // namespace boost::xpressive::detail
#endif

View File

@@ -0,0 +1,102 @@
/*=============================================================================
Copyright (c) 2001-2003 Joel de Guzman
http://spirit.sourceforge.net/
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef BOOST_XPRESSIVE_SPIRIT_RANGE_RUN_HPP_EAN_10_04_2005
#define BOOST_XPRESSIVE_SPIRIT_RANGE_RUN_HPP_EAN_10_04_2005
///////////////////////////////////////////////////////////////////////////////
#include <vector>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace xpressive { namespace detail
{
///////////////////////////////////////////////////////////////////////////
//
// range class
//
// Implements a closed range of values. This class is used in
// the implementation of the range_run class.
//
// { Low level implementation detail }
// { Not to be confused with spirit::range }
//
///////////////////////////////////////////////////////////////////////////
template<typename Char>
struct range
{
range(Char first, Char last);
bool is_valid() const;
bool includes(Char v) const;
bool includes(range const &r) const;
bool overlaps(range const &r) const;
void merge(range const &r);
Char first_;
Char last_;
};
//////////////////////////////////
template<typename Char>
struct range_compare
{
bool operator()(range<Char> const &x, range<Char> const &y) const
{
return x.first_ < y.first_;
}
};
///////////////////////////////////////////////////////////////////////////
//
// 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 implementation detail }
//
///////////////////////////////////////////////////////////////////////////
template<typename Char>
struct range_run
{
typedef range<Char> range_type;
typedef std::vector<range_type> run_type;
typedef typename run_type::iterator iterator;
typedef typename run_type::const_iterator const_iterator;
void swap(range_run& rr);
bool empty() const;
bool test(Char v) const;
template<typename Traits>
bool test(Char v, Traits const &tr) const;
void set(range_type const &r);
void clear(range_type const &r);
void clear();
const_iterator begin() const;
const_iterator end() const;
private:
void merge(iterator iter, range_type const &r);
run_type run_;
};
}}} // namespace boost::xpressive::detail
#endif

View File

@@ -0,0 +1,235 @@
/*=============================================================================
Copyright (c) 2001-2003 Joel de Guzman
http://spirit.sourceforge.net/
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef BOOST_XPRESSIVE_SPIRIT_RANGE_RUN_IPP
#define BOOST_XPRESSIVE_SPIRIT_RANGE_RUN_IPP
///////////////////////////////////////////////////////////////////////////////
#include <algorithm> // for std::lower_bound
#include <boost/limits.hpp>
#include <boost/assert.hpp>
#include <boost/xpressive/detail/utility/chset/range_run.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace xpressive { namespace detail
{
///////////////////////////////////////////////////////////////////////
//
// range class implementation
//
///////////////////////////////////////////////////////////////////////
template<typename Char>
inline range<Char>::range(Char first, Char last)
: first_(first)
, last_(last)
{
}
//////////////////////////////////
template<typename Char>
inline bool range<Char>::is_valid() const
{
return this->first_ <= this->last_;
}
//////////////////////////////////
template<typename Char>
inline bool range<Char>::includes(range<Char> const &r) const
{
return (this->first_ <= r.first_) && (this->last_ >= r.last_);
}
//////////////////////////////////
template<typename Char>
inline bool range<Char>::includes(Char v) const
{
return (this->first_ <= v) && (this->last_ >= v);
}
//////////////////////////////////
template<typename Char>
inline bool range<Char>::overlaps(range<Char> const &r) const
{
Char decr_first = (std::min)(this->first_, Char(this->first_-1));
Char incr_last = (std::max)(this->last_, Char(this->last_+1));
return (decr_first <= r.last_) && (incr_last >= r.first_);
}
//////////////////////////////////
template<typename Char>
inline void range<Char>::merge(range<Char> const &r)
{
this->first_ = (std::min)(this->first_, r.first_);
this->last_ = (std::max)(this->last_, r.last_);
}
///////////////////////////////////////////////////////////////////////
//
// range_run class implementation
//
///////////////////////////////////////////////////////////////////////
template<typename Char>
inline bool range_run<Char>::empty() const
{
return this->run_.empty();
}
template<typename Char>
inline bool range_run<Char>::test(Char v) const
{
if(this->run_.empty())
{
return false;
}
const_iterator iter = std::lower_bound(
this->run_.begin()
, this->run_.end()
, range<Char>(v, v)
, range_compare<Char>()
);
return (iter != this->run_.end() && iter->includes(v))
|| (iter != this->run_.begin() && (--iter)->includes(v));
}
template<typename Char>
template<typename Traits>
inline bool range_run<Char>::test(Char v, Traits const &tr) const
{
const_iterator begin = this->run_.begin();
const_iterator end = this->run_.end();
for(; begin != end; ++begin)
{
if(tr.in_range_nocase(begin->first_, begin->last_, v))
{
return true;
}
}
return false;
}
//////////////////////////////////
template<typename Char>
inline void range_run<Char>::swap(range_run<Char> &rr)
{
this->run_.swap(rr.run_);
}
//////////////////////////////////
template<typename Char>
void range_run<Char>::merge(iterator iter, range<Char> const &r)
{
BOOST_ASSERT(iter != this->run_.end());
iter->merge(r);
iterator i = iter;
while(++i != this->run_.end() && iter->overlaps(*i))
{
iter->merge(*i);
}
this->run_.erase(++iter, i);
}
//////////////////////////////////
template<typename Char>
void range_run<Char>::set(range<Char> const &r)
{
BOOST_ASSERT(r.is_valid());
if(!this->run_.empty())
{
iterator iter = std::lower_bound(this->run_.begin(), this->run_.end(), r, range_compare<Char>());
if((iter != this->run_.end() && iter->includes(r)) ||
(iter != this->run_.begin() && (iter - 1)->includes(r)))
{
return;
}
else if(iter != this->run_.begin() && (iter - 1)->overlaps(r))
{
this->merge(--iter, r);
}
else if(iter != this->run_.end() && iter->overlaps(r))
{
this->merge(iter, r);
}
else
{
this->run_.insert(iter, r);
}
}
else
{
this->run_.push_back(r);
}
}
//////////////////////////////////
template<typename Char>
void range_run<Char>::clear(range<Char> const &r)
{
BOOST_ASSERT(r.is_valid());
if(!this->run_.empty())
{
iterator iter = std::lower_bound(this->run_.begin(), this->run_.end(), r, range_compare<Char>());
iterator left_iter;
if((iter != this->run_.begin()) &&
(left_iter = (iter - 1))->includes(r.first_))
{
if(left_iter->last_ > r.last_)
{
Char save_last = left_iter->last_;
left_iter->last_ = r.first_-1;
this->run_.insert(iter, range<Char>(r.last_+1, save_last));
return;
}
else
{
left_iter->last_ = r.first_-1;
}
}
iterator i = iter;
for(; i != this->run_.end() && r.includes(*i); ++i) {}
if(i != this->run_.end() && i->includes(r.last_))
{
i->first_ = r.last_+1;
}
this->run_.erase(iter, i);
}
}
//////////////////////////////////
template<typename Char>
inline void range_run<Char>::clear()
{
this->run_.clear();
}
//////////////////////////////////
template<typename Char>
inline typename range_run<Char>::const_iterator range_run<Char>::begin() const
{
return this->run_.begin();
}
//////////////////////////////////
template<typename Char>
inline typename range_run<Char>::const_iterator range_run<Char>::end() const
{
return this->run_.end();
}
}}} // namespace boost::xpressive::detail
#endif

View File

@@ -0,0 +1,309 @@
///////////////////////////////////////////////////////////////////////////////
// cons.hpp
//
// Copyright 2008 Eric Niebler. 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_XPRESSIVE_DETAIL_UTILITY_CONS_HPP_EAN_11_19_2005
#define BOOST_XPRESSIVE_DETAIL_UTILITY_CONS_HPP_EAN_11_19_2005
#include <boost/version.hpp>
#if BOOST_VERSION >= 103300
// In Boost 1.33+, we have a cons list in Fusion, so just include it.
# if BOOST_VERSION >= 103500
# include <boost/fusion/include/cons.hpp> // Boost 1.35+ has Fusion2
# else
# include <boost/spirit/fusion/sequence/cons.hpp> // Fusion1
# endif
#else
// For earlier versions of Boost, put the definition of cons here
# include <boost/call_traits.hpp>
# include <boost/mpl/if.hpp>
# include <boost/mpl/eval_if.hpp>
# include <boost/mpl/identity.hpp>
# include <boost/type_traits/is_const.hpp>
# include <boost/type_traits/add_const.hpp>
# include <boost/type_traits/add_reference.hpp>
# include <boost/spirit/fusion/detail/config.hpp>
# include <boost/spirit/fusion/detail/access.hpp>
# include <boost/spirit/fusion/iterator/next.hpp>
# include <boost/spirit/fusion/iterator/equal_to.hpp>
# include <boost/spirit/fusion/iterator/as_fusion_iterator.hpp>
# include <boost/spirit/fusion/iterator/detail/iterator_base.hpp>
# include <boost/spirit/fusion/sequence/begin.hpp>
# include <boost/spirit/fusion/sequence/end.hpp>
# include <boost/spirit/fusion/sequence/as_fusion_sequence.hpp>
# include <boost/spirit/fusion/sequence/detail/sequence_base.hpp>
namespace boost { namespace fusion
{
struct nil;
struct cons_tag;
template <typename Car, typename Cdr>
struct cons;
struct cons_iterator_tag;
template <typename Cons>
struct cons_iterator;
namespace cons_detail
{
template <typename Iterator>
struct deref_traits_impl
{
typedef typename Iterator::cons_type cons_type;
typedef typename cons_type::car_type value_type;
typedef typename mpl::eval_if<
is_const<cons_type>
, add_reference<typename add_const<value_type>::type>
, add_reference<value_type> >::type
type;
static type
call(Iterator const& i)
{
return detail::ref(i.cons.car);
}
};
template <typename Iterator>
struct next_traits_impl
{
typedef typename Iterator::cons_type cons_type;
typedef typename cons_type::cdr_type cdr_type;
typedef cons_iterator<
typename mpl::eval_if<
is_const<cons_type>
, add_const<cdr_type>
, mpl::identity<cdr_type>
>::type>
type;
static type
call(Iterator const& i)
{
return type(detail::ref(i.cons.cdr));
}
};
template <typename Iterator>
struct value_traits_impl
{
typedef typename Iterator::cons_type cons_type;
typedef typename cons_type::car_type type;
};
template <typename Cons>
struct begin_traits_impl
{
typedef cons_iterator<Cons> type;
static type
call(Cons& t)
{
return type(t);
}
};
template <typename Cons>
struct end_traits_impl
{
typedef cons_iterator<
typename mpl::if_<is_const<Cons>, nil const, nil>::type>
type;
static type
call(Cons& t)
{
FUSION_RETURN_DEFAULT_CONSTRUCTED;
}
};
} // namespace cons_detail
namespace meta
{
template <typename Tag>
struct deref_impl;
template <>
struct deref_impl<cons_iterator_tag>
{
template <typename Iterator>
struct apply : cons_detail::deref_traits_impl<Iterator> {};
};
template <typename Tag>
struct next_impl;
template <>
struct next_impl<cons_iterator_tag>
{
template <typename Iterator>
struct apply : cons_detail::next_traits_impl<Iterator> {};
};
template <typename Tag>
struct value_impl;
template <>
struct value_impl<cons_iterator_tag>
{
template <typename Iterator>
struct apply : cons_detail::value_traits_impl<Iterator> {};
};
template <typename Tag>
struct begin_impl;
template <>
struct begin_impl<cons_tag>
{
template <typename Sequence>
struct apply : cons_detail::begin_traits_impl<Sequence>
{};
};
template <typename Tag>
struct end_impl;
template <>
struct end_impl<cons_tag>
{
template <typename Sequence>
struct apply : cons_detail::end_traits_impl<Sequence>
{};
};
} // namespace meta
template <typename Cons = nil>
struct cons_iterator : iterator_base<cons_iterator<Cons> >
{
typedef cons_iterator_tag tag;
typedef Cons cons_type;
explicit cons_iterator(cons_type& cons_)
: cons(cons_) {}
cons_type& cons;
};
template <>
struct cons_iterator<nil> : iterator_base<cons_iterator<nil> >
{
typedef cons_iterator_tag tag;
typedef nil cons_type;
cons_iterator() {}
explicit cons_iterator(nil const&) {}
};
template <>
struct cons_iterator<nil const> : iterator_base<cons_iterator<nil const> >
{
typedef cons_iterator_tag tag;
typedef nil const cons_type;
cons_iterator() {}
explicit cons_iterator(nil const&) {}
};
struct nil : sequence_base<nil>
{
typedef cons_tag tag;
typedef void_t car_type;
typedef void_t cdr_type;
};
template <typename Car, typename Cdr = nil>
struct cons : sequence_base<cons<Car,Cdr> >
{
typedef cons_tag tag;
typedef typename call_traits<Car>::value_type car_type;
typedef Cdr cdr_type;
cons()
: car(), cdr() {}
explicit cons(
typename call_traits<Car>::param_type car_
, typename call_traits<Cdr>::param_type cdr_ = Cdr())
: car(car_), cdr(cdr_) {}
car_type car;
cdr_type cdr;
};
template <typename Car>
inline cons<Car>
make_cons(Car const& car)
{
return cons<Car>(car);
}
template <typename Car, typename Cdr>
inline cons<Car, Cdr>
make_cons(Car const& car, Cdr const& cdr)
{
return cons<Car, Cdr>(car, cdr);
}
}} // namespace boost::fusion
namespace boost { namespace mpl
{
template <typename Tag>
struct begin_impl;
template <typename Tag>
struct end_impl;
template <>
struct begin_impl<fusion::cons_tag>
: fusion::meta::begin_impl<fusion::cons_tag>
{
};
template <>
struct end_impl<fusion::cons_tag>
: fusion::meta::end_impl<fusion::cons_tag>
{
};
}} // namespace boost::mpl
#endif
// Before Boost v1.33.1, Fusion cons lists were not valid MPL sequences.
#if BOOST_VERSION < 103301
namespace boost { namespace mpl
{
template<typename Iterator>
struct next;
template<typename Cons>
struct next<fusion::cons_iterator<Cons> >
: fusion::cons_detail::next_traits_impl<fusion::cons_iterator<Cons> >
{
};
template<typename Iterator>
struct deref;
template<typename Cons>
struct deref<fusion::cons_iterator<Cons> >
: fusion::cons_detail::value_traits_impl<fusion::cons_iterator<Cons> >
{
};
}} // namespace boost::mpl
#endif
#endif

View File

@@ -0,0 +1,84 @@
//////////////////////////////////////////////////////////////////////////////
// (c) Copyright Andreas Huber Doenni 2002-2005, Eric Niebler 2006
// Distributed under the Boost Software License, Version 1.0. (See accompany-
// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_XPRESSIVE_DETAIL_UTILITY_COUNTED_BASE_HPP_EAN_04_16_2006
#define BOOST_XPRESSIVE_DETAIL_UTILITY_COUNTED_BASE_HPP_EAN_04_16_2006
#include <boost/assert.hpp>
#include <boost/checked_delete.hpp>
#include <boost/detail/atomic_count.hpp>
namespace boost { namespace xpressive { namespace detail
{
template<typename Derived>
struct counted_base_access;
//////////////////////////////////////////////////////////////////////////////
// counted_base
template<typename Derived>
struct counted_base
{
long use_count() const
{
return this->count_;
}
protected:
counted_base()
: count_(0)
{
}
counted_base(counted_base<Derived> const &)
: count_(0)
{
}
counted_base &operator =(counted_base<Derived> const &)
{
return *this;
}
private:
friend struct counted_base_access<Derived>;
mutable boost::detail::atomic_count count_;
};
//////////////////////////////////////////////////////////////////////////////
// counted_base_access
template<typename Derived>
struct counted_base_access
{
static void add_ref(counted_base<Derived> const *that)
{
++that->count_;
}
static void release(counted_base<Derived> const *that)
{
BOOST_ASSERT(0 < that->count_);
if(0 == --that->count_)
{
boost::checked_delete(static_cast<Derived const *>(that));
}
}
};
template<typename Derived>
inline void intrusive_ptr_add_ref(counted_base<Derived> const *that)
{
counted_base_access<Derived>::add_ref(that);
}
template<typename Derived>
inline void intrusive_ptr_release(counted_base<Derived> const *that)
{
counted_base_access<Derived>::release(that);
}
}}} // namespace boost::xpressive::detail
#endif

View File

@@ -0,0 +1,25 @@
///////////////////////////////////////////////////////////////////////////////
// dont_care.hpp
//
// Copyright 2008 Eric Niebler. 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_XPRESSIVE_DETAIL_UTILITY_DONT_CARE_HPP_EAN_10_04_2005
#define BOOST_XPRESSIVE_DETAIL_UTILITY_DONT_CARE_HPP_EAN_10_04_2005
namespace boost { namespace xpressive { namespace detail
{
///////////////////////////////////////////////////////////////////////////////
// for function arguments we don't care about
struct dont_care
{
dont_care() {}
template<typename T>
dont_care(T const &) {}
};
}}}
#endif

View File

@@ -0,0 +1,178 @@
///////////////////////////////////////////////////////////////////////////////
// hash_peek_bitset.hpp
//
// Copyright 2008 Eric Niebler. 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_XPRESSIVE_DETAIL_HASH_PEEK_BITSET_HPP_EAN_10_04_2005
#define BOOST_XPRESSIVE_DETAIL_HASH_PEEK_BITSET_HPP_EAN_10_04_2005
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
# pragma warning(push)
# pragma warning(disable : 4100) // unreferenced formal parameter
# pragma warning(disable : 4127) // conditional expression constant
#endif
#include <bitset>
#include <string> // for std::char_traits
#include <boost/xpressive/detail/utility/chset/basic_chset.ipp>
namespace boost { namespace xpressive { namespace detail
{
///////////////////////////////////////////////////////////////////////////////
// hash_peek_bitset
//
template<typename Char>
struct hash_peek_bitset
{
typedef Char char_type;
typedef typename std::char_traits<char_type>::int_type int_type;
hash_peek_bitset()
: icase_(false)
, bset_()
{
}
std::size_t count() const
{
return this->bset_.count();
}
void set_all()
{
this->icase_ = false;
this->bset_.set();
}
template<typename Traits>
void set_char(char_type ch, bool icase, Traits const &tr)
{
if(this->test_icase_(icase))
{
ch = icase ? tr.translate_nocase(ch) : tr.translate(ch);
this->bset_.set(tr.hash(ch));
}
}
template<typename Traits>
void set_range(char_type from, char_type to, bool no, bool icase, Traits const &tr)
{
int_type ifrom = std::char_traits<char_type>::to_int_type(from);
int_type ito = std::char_traits<char_type>::to_int_type(to);
BOOST_ASSERT(ifrom <= ito);
// bound the computational complexity. BUGBUG could set the inverse range
if(no || 256 < (ito - ifrom))
{
this->set_all();
}
else if(this->test_icase_(icase))
{
for(int_type i = ifrom; i <= ito; ++i)
{
char_type ch = std::char_traits<char_type>::to_char_type(i);
ch = icase ? tr.translate_nocase(ch) : tr.translate(ch);
this->bset_.set(tr.hash(ch));
}
}
}
template<typename Traits>
void set_class(typename Traits::char_class_type char_class, bool no, Traits const &tr)
{
if(1 != sizeof(char_type))
{
// wide character set, no efficient way of filling in the bitset, so set them all to 1
this->set_all();
}
else
{
for(std::size_t i = 0; i <= UCHAR_MAX; ++i)
{
char_type ch = std::char_traits<char_type>::to_char_type(static_cast<int_type>(i));
if(no != tr.isctype(ch, char_class))
{
this->bset_.set(i);
}
}
}
}
void set_bitset(hash_peek_bitset<Char> const &that)
{
if(this->test_icase_(that.icase()))
{
this->bset_ |= that.bset_;
}
}
void set_charset(basic_chset_8bit<Char> const &that, bool icase)
{
if(this->test_icase_(icase))
{
this->bset_ |= that.base();
}
}
bool icase() const
{
return this->icase_;
}
template<typename Traits>
bool test(char_type ch, Traits const &tr) const
{
ch = this->icase_ ? tr.translate_nocase(ch) : tr.translate(ch);
return this->bset_.test(tr.hash(ch));
}
template<typename Traits>
bool test(char_type ch, Traits const &tr, mpl::false_) const
{
BOOST_ASSERT(!this->icase_);
return this->bset_.test(tr.hash(tr.translate(ch)));
}
template<typename Traits>
bool test(char_type ch, Traits const &tr, mpl::true_) const
{
BOOST_ASSERT(this->icase_);
return this->bset_.test(tr.hash(tr.translate_nocase(ch)));
}
private:
// Make sure all sub-expressions being merged have the same case-sensitivity
bool test_icase_(bool icase)
{
std::size_t count = this->bset_.count();
if(256 == count)
{
return false; // all set already, nothing to do
}
else if(0 != count && this->icase_ != icase)
{
this->set_all(); // icase mismatch! set all and bail
return false;
}
this->icase_ = icase;
return true;
}
bool icase_;
std::bitset<256> bset_;
};
}}} // namespace boost::xpressive::detail
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma warning(pop)
#endif
#endif

View File

@@ -0,0 +1,24 @@
///////////////////////////////////////////////////////////////////////////////
// ignore_unused.hpp
//
// Copyright 2008 Eric Niebler. 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_XPRESSIVE_DETAIL_UTILITY_IGNORE_UNUSED_HPP_EAN_10_04_2005
#define BOOST_XPRESSIVE_DETAIL_UTILITY_IGNORE_UNUSED_HPP_EAN_10_04_2005
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include "boost/proto/detail/ignore_unused.hpp"
namespace boost { namespace xpressive { namespace detail
{
using boost::proto::detail::ignore_unused;
}}}
#endif

View File

@@ -0,0 +1,85 @@
///////////////////////////////////////////////////////////////////////////////
// literals.hpp
//
// Copyright 2008 Eric Niebler. 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_XPRESSIVE_DETAIL_UTILITY_LITERALS_HPP_EAN_10_04_2005
#define BOOST_XPRESSIVE_DETAIL_UTILITY_LITERALS_HPP_EAN_10_04_2005
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include <boost/config.hpp> // for BOOST_STATIC_CONSTANT
#include <boost/cstdint.hpp> // for BOOST_STATIC_CONSTANT
#include <boost/detail/workaround.hpp>
namespace boost { namespace xpressive { namespace detail
{
///////////////////////////////////////////////////////////////////////////////
// char_literal
//
template<typename Char, boost::intmax_t Ch, boost::intmax_t Wch>
struct char_literal;
template<typename Char, boost::intmax_t Ch>
struct char_literal<Char, Ch, Ch>
{
BOOST_STATIC_CONSTANT(boost::intmax_t, value = Ch);
};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
template<typename Char, boost::intmax_t Ch>
boost::intmax_t const char_literal<Char, Ch, Ch>::value;
#endif
template<typename Ch>
struct string_literal;
template<>
struct string_literal<char>
{
static char const *pick(char const *cstr, wchar_t const *)
{
return cstr;
}
static char pick(char ch, wchar_t)
{
return ch;
}
};
template<>
struct string_literal<wchar_t>
{
static wchar_t const *pick(char const *, wchar_t const *cstr)
{
return cstr;
}
static wchar_t pick(char, wchar_t ch)
{
return ch;
}
};
#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206))
# define BOOST_XPR_CHAR_(Char, ch) ch
# define BOOST_XPR_CSTR_(Char, st) boost::xpressive::detail::string_literal<Char>::pick(st, L##st)
#else
# define BOOST_XPR_CHAR_(Char, ch) boost::xpressive::detail::char_literal<Char, ch, L##ch>::value
# define BOOST_XPR_CSTR_(Char, st) boost::xpressive::detail::string_literal<Char>::pick(st, L##st)
#endif
}}} // namespace boost::xpressive::detail
#endif

View File

@@ -0,0 +1,25 @@
///////////////////////////////////////////////////////////////////////////////
// never_true.hpp
//
// Copyright 2008 Eric Niebler. 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_XPRESSIVE_DETAIL_UTILITY_NEVER_TRUE_HPP_EAN_10_04_2005
#define BOOST_XPRESSIVE_DETAIL_UTILITY_NEVER_TRUE_HPP_EAN_10_04_2005
#include <boost/mpl/bool.hpp>
namespace boost { namespace xpressive { namespace detail
{
// for use in static asserts
template<typename T>
struct never_true
: mpl::false_
{
};
}}}
#endif

View File

@@ -0,0 +1,55 @@
///////////////////////////////////////////////////////////////////////////////
// save_restore.hpp
//
// Copyright 2008 Eric Niebler. 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_XPRESSIVE_DETAIL_UTILITY_SAVE_RESTORE_HPP_EAN_10_04_2005
#define BOOST_XPRESSIVE_DETAIL_UTILITY_SAVE_RESTORE_HPP_EAN_10_04_2005
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include <boost/noncopyable.hpp>
namespace boost { namespace xpressive { namespace detail
{
template<typename T>
struct save_restore
: private noncopyable
{
explicit save_restore(T &t)
: ref(t)
, val(t)
{
}
save_restore(T &t, T const &n)
: ref(t)
, val(t)
{
this->ref = n;
}
~save_restore()
{
this->ref = this->val;
}
void restore()
{
this->ref = this->val;
}
private:
T &ref;
T const val;
};
}}}
#endif

View File

@@ -0,0 +1,259 @@
///////////////////////////////////////////////////////////////////////////////
// sequence_stack.hpp
//
// Copyright 2008 Eric Niebler. 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_XPRESSIVE_DETAIL_SEQUENCE_STACK_HPP_EAN_10_04_2005
#define BOOST_XPRESSIVE_DETAIL_SEQUENCE_STACK_HPP_EAN_10_04_2005
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
# pragma warning(push)
# pragma warning(disable : 4127) // conditional expression constant
#endif
#include <algorithm>
#include <functional>
namespace boost { namespace xpressive { namespace detail
{
struct fill_t {} const fill = {};
//////////////////////////////////////////////////////////////////////////
// sequence_stack
//
// For storing a stack of sequences of type T, where each sequence
// is guaranteed to be stored in contiguous memory.
template<typename T>
struct sequence_stack
{
private:
static T *allocate(std::size_t size, T const &t)
{
std::size_t i = 0;
T *p = (T *)::operator new(size * sizeof(T));
try
{
for(; i < size; ++i)
::new((void *)(p+i)) T(t);
}
catch(...)
{
deallocate(p, i);
throw;
}
return p;
}
static void deallocate(T *p, std::size_t i)
{
while(i-- > 0)
(p+i)->~T();
::operator delete(p);
}
struct chunk
{
chunk(std::size_t size, T const &t, std::size_t count, chunk *back, chunk *next)
: begin_(allocate(size, t))
, curr_(begin_ + count)
, end_(begin_ + size)
, back_(back)
, next_(next)
{
if(this->back_)
this->back_->next_ = this;
if(this->next_)
this->next_->back_ = this;
}
~chunk()
{
deallocate(this->begin_, this->size());
}
std::size_t size() const
{
return static_cast<std::size_t>(this->end_ - this->begin_);
}
T *const begin_, *curr_, *const end_;
chunk *back_, *next_;
private:
chunk &operator =(chunk const &);
};
chunk *current_chunk_;
// Cache these for faster access
T *begin_;
T *curr_;
T *end_;
T *grow_(std::size_t count, T const &t)
{
if(this->current_chunk_)
{
// write the cached value of current into the expr.
// OK to do this even if later statements throw.
this->current_chunk_->curr_ = this->curr_;
// Do we have a expr with enough available memory already?
if(this->current_chunk_->next_ && count <= this->current_chunk_->next_->size())
{
this->current_chunk_ = this->current_chunk_->next_;
this->curr_ = this->current_chunk_->curr_ = this->current_chunk_->begin_ + count;
this->end_ = this->current_chunk_->end_;
this->begin_ = this->current_chunk_->begin_;
std::fill_n(this->begin_, count, t);
return this->begin_;
}
// grow exponentially
std::size_t new_size = (std::max)(count, static_cast<std::size_t>(this->current_chunk_->size() * 1.5));
// Create a new expr and insert it into the list
this->current_chunk_ = new chunk(new_size, t, count, this->current_chunk_, this->current_chunk_->next_);
}
else
{
// first chunk is 256
std::size_t new_size = (std::max)(count, static_cast<std::size_t>(256U));
// Create a new expr and insert it into the list
this->current_chunk_ = new chunk(new_size, t, count, 0, 0);
}
this->begin_ = this->current_chunk_->begin_;
this->curr_ = this->current_chunk_->curr_;
this->end_ = this->current_chunk_->end_;
return this->begin_;
}
void unwind_chunk_()
{
// write the cached value of curr_ into current_chunk_
this->current_chunk_->curr_ = this->begin_;
// make the previous chunk the current
this->current_chunk_ = this->current_chunk_->back_;
// update the cache
this->begin_ = this->current_chunk_->begin_;
this->curr_ = this->current_chunk_->curr_;
this->end_ = this->current_chunk_->end_;
}
bool in_current_chunk(T *ptr) const
{
return !std::less<void*>()(ptr, this->begin_) && std::less<void*>()(ptr, this->end_);
}
public:
sequence_stack()
: current_chunk_(0)
, begin_(0)
, curr_(0)
, end_(0)
{
}
~sequence_stack()
{
this->clear();
}
// walk to the front of the linked list
void unwind()
{
if(this->current_chunk_)
{
while(this->current_chunk_->back_)
{
this->current_chunk_->curr_ = this->current_chunk_->begin_;
this->current_chunk_ = this->current_chunk_->back_;
}
this->begin_ = this->curr_ = this->current_chunk_->curr_ = this->current_chunk_->begin_;
this->end_ = this->current_chunk_->end_;
}
}
void clear()
{
// walk to the front of the list
this->unwind();
// delete the list
for(chunk *next; this->current_chunk_; this->current_chunk_ = next)
{
next = this->current_chunk_->next_;
delete this->current_chunk_;
}
this->begin_ = this->curr_ = this->end_ = 0;
}
T *push_sequence(std::size_t count, T const &t)
{
// This is the ptr to return
T *ptr = this->curr_;
// Advance the high-water mark
this->curr_ += count;
// Check to see if we have overflowed this buffer
if(std::less<void*>()(this->end_, this->curr_))
{
// oops, back this out.
this->curr_ = ptr;
// allocate a new block and return a ptr to the new memory
return this->grow_(count, t);
}
return ptr;
}
T *push_sequence(std::size_t count, T const &t, fill_t)
{
T *ptr = this->push_sequence(count, t);
std::fill_n(ptr, count, t);
return ptr;
}
void unwind_to(T *ptr)
{
while(!this->in_current_chunk(ptr))
{
// completely unwind the current chunk, move to the previous chunk
this->unwind_chunk_();
}
this->current_chunk_->curr_ = this->curr_ = ptr;
}
// shrink-to-fit: remove any unused nodes in the chain
void conserve()
{
if(this->current_chunk_)
{
for(chunk *next; this->current_chunk_->next_; this->current_chunk_->next_ = next)
{
next = this->current_chunk_->next_->next_;
delete this->current_chunk_->next_;
}
}
}
};
}}} // namespace boost::xpressive::detail
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma warning(pop)
#endif
#endif

View File

@@ -0,0 +1,278 @@
///////////////////////////////////////////////////////////////////////////////
/// \file symbols.hpp
/// Contains the Ternary Search Trie implementation.
/// Based on the following papers:
/// J. Bentley and R. Sedgewick. (1998) Ternary search trees. Dr. Dobbs Journal
/// G. Badr and B.J. Oommen. (2005) Self-Adjusting of Ternary Search Tries Using
/// Conditional Rotations and Randomized Heuristics
//
// Copyright 2007 David Jenkins.
// Copyright 2007 Eric Niebler.
//
// 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_XPRESSIVE_DETAIL_SYMBOLS_HPP_DRJ_06_11_2007
#define BOOST_XPRESSIVE_DETAIL_SYMBOLS_HPP_DRJ_06_11_2007
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include <boost/noncopyable.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/value_type.hpp>
#include <boost/range/const_iterator.hpp>
#include <boost/shared_ptr.hpp>
namespace boost { namespace xpressive { namespace detail
{
///////////////////////////////////////////////////////////////////////////////
// symbols (using a ternary search trie)
//
template<typename Map>
struct symbols
{
typedef typename range_value<Map>::type::first_type key_type;
typedef typename range_value<Map>::type::second_type value_type;
typedef typename range_value<key_type>::type char_type;
typedef typename range_const_iterator<Map>::type iterator;
typedef typename range_const_iterator<key_type>::type key_iterator;
typedef value_type const *result_type;
// copies of this symbol table share the TST
template<typename Trans>
void load(Map const &map, Trans trans)
{
iterator begin = boost::begin(map);
iterator end = boost::end(map);
node* root_p = this->root.get();
for(; begin != end; ++begin)
{
key_iterator kbegin = boost::begin(begin->first);
key_iterator kend = boost::end(begin->first);
root_p = this->insert(root_p, kbegin, kend, &begin->second, trans);
}
this->root.reset(root_p);
}
template<typename BidiIter, typename Trans>
result_type operator ()(BidiIter &begin, BidiIter end, Trans trans) const
{
return this->search(begin, end, trans, this->root.get());
}
template<typename Sink>
void peek(Sink const &sink) const
{
this->peek_(this->root.get(), sink);
}
private:
///////////////////////////////////////////////////////////////////////////////
// struct node : a node in the TST.
// The "eq" field stores the result pointer when ch is zero.
//
struct node
: boost::noncopyable
{
node(char_type c)
: ch(c)
, lo(0)
, eq(0)
, hi(0)
#ifdef BOOST_DISABLE_THREADS
, tau(0)
#endif
{}
~node()
{
delete lo;
if (ch)
delete eq;
delete hi;
}
void swap(node& that)
{
std::swap(ch, that.ch);
std::swap(lo, that.lo);
std::swap(eq, that.eq);
std::swap(hi, that.hi);
#ifdef BOOST_DISABLE_THREADS
std::swap(tau, that.tau);
#endif
}
char_type ch;
node* lo;
union
{
node* eq;
result_type result;
};
node* hi;
#ifdef BOOST_DISABLE_THREADS
long tau;
#endif
};
///////////////////////////////////////////////////////////////////////////////
// insert : insert a string into the TST
//
template<typename Trans>
node* insert(node* p, key_iterator &begin, key_iterator end, result_type r, Trans trans) const
{
char_type c1 = 0;
if(begin != end)
{
c1 = trans(*begin);
}
if(!p)
{
p = new node(c1);
}
if(c1 < p->ch)
{
p->lo = this->insert(p->lo, begin, end, r, trans);
}
else if(c1 == p->ch)
{
if(0 == c1)
{
p->result = r;
}
else
{
p->eq = this->insert(p->eq, ++begin, end, r, trans);
}
}
else
{
p->hi = this->insert(p->hi, begin, end, r, trans);
}
return p;
}
#ifdef BOOST_DISABLE_THREADS
///////////////////////////////////////////////////////////////////////////////
// conditional rotation : the goal is to minimize the overall
// weighted path length of each binary search tree
//
bool cond_rotation(bool left, node* const i, node* const j) const
{
// don't rotate top node in binary search tree
if (i == j)
return false;
// calculate psi (the rotation condition)
node* const k = (left ? i->hi : i->lo);
long psi = 2*i->tau - j->tau - (k ? k->tau : 0);
if (psi <= 0)
return false;
// recalculate the tau values
j->tau += -i->tau + (k ? k->tau : 0);
i->tau += j->tau - (k ? k->tau : 0);
// fixup links and swap nodes
if (left)
{
j->lo = k;
i->hi = i;
}
else
{
j->hi = k;
i->lo = i;
}
(*i).swap(*j);
return true;
}
#endif
///////////////////////////////////////////////////////////////////////////////
// search : find a string in the TST
//
template<typename BidiIter, typename Trans>
result_type search(BidiIter &begin, BidiIter end, Trans trans, node* p) const
{
result_type r = 0;
node* p2 = p;
bool left = false;
char_type c1 = (begin != end ? trans(*begin) : 0);
while(p)
{
#ifdef BOOST_DISABLE_THREADS
++p->tau;
#endif
if(c1 == p->ch)
{
// conditional rotation test
#ifdef BOOST_DISABLE_THREADS
if (this->cond_rotation(left, p, p2))
p = p2;
#endif
if (0 == p->ch)
{
// it's a match!
r = p->result;
}
if(begin == end)
break;
++begin;
p = p->eq;
// search for the longest match first
r = search(begin,end,trans,p);
if (0 == r)
{
// search for a match ending here
r = search(end,end,trans,p);
if (0 == r)
{
--begin;
}
}
break;
}
else if(c1 < p->ch)
{
left = true;
p2 = p;
p = p->lo;
}
else // (c1 > p->ch)
{
left = false;
p2 = p;
p = p->hi;
}
}
return r;
}
template<typename Sink>
void peek_(node const *const &p, Sink const &sink) const
{
if(p)
{
sink(p->ch);
this->peek_(p->lo, sink);
this->peek_(p->hi, sink);
}
}
boost::shared_ptr<node> root;
};
}}} // namespace boost::xpressive::detail
#endif

View File

@@ -0,0 +1,494 @@
///////////////////////////////////////////////////////////////////////////////
// tracking_ptr.hpp
//
// Copyright 2008 Eric Niebler. 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_XPRESSIVE_DETAIL_UTILITY_TRACKING_PTR_HPP_EAN_10_04_2005
#define BOOST_XPRESSIVE_DETAIL_UTILITY_TRACKING_PTR_HPP_EAN_10_04_2005
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#ifdef BOOST_XPRESSIVE_DEBUG_TRACKING_POINTER
# include <iostream>
#endif
#include <set>
#include <functional>
#include <boost/config.hpp>
#include <boost/assert.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/intrusive_ptr.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/detail/atomic_count.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <boost/iterator/filter_iterator.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
namespace boost { namespace xpressive { namespace detail
{
template<typename Type>
struct tracking_ptr;
template<typename Derived>
struct enable_reference_tracking;
///////////////////////////////////////////////////////////////////////////////
// weak_iterator
// steps through a set of weak_ptr, converts to shared_ptrs on the fly and
// removes from the set the weak_ptrs that have expired.
template<typename Derived>
struct weak_iterator
: iterator_facade
<
weak_iterator<Derived>
, shared_ptr<Derived> const
, std::forward_iterator_tag
>
{
typedef std::set<weak_ptr<Derived> > set_type;
typedef typename set_type::iterator base_iterator;
weak_iterator()
: cur_()
, iter_()
, set_(0)
{
}
weak_iterator(base_iterator iter, set_type *set)
: cur_()
, iter_(iter)
, set_(set)
{
this->satisfy_();
}
private:
friend class boost::iterator_core_access;
shared_ptr<Derived> const &dereference() const
{
return this->cur_;
}
void increment()
{
++this->iter_;
this->satisfy_();
}
bool equal(weak_iterator<Derived> const &that) const
{
return this->iter_ == that.iter_;
}
void satisfy_()
{
while(this->iter_ != this->set_->end())
{
this->cur_ = this->iter_->lock();
if(this->cur_)
return;
base_iterator tmp = this->iter_++;
this->set_->erase(tmp);
}
this->cur_.reset();
}
shared_ptr<Derived> cur_;
base_iterator iter_;
set_type *set_;
};
///////////////////////////////////////////////////////////////////////////////
// filter_self
// for use with a filter_iterator to filter a node out of a list of dependencies
template<typename Derived>
struct filter_self
: std::unary_function<shared_ptr<Derived>, bool>
{
filter_self(enable_reference_tracking<Derived> *self)
: self_(self)
{
}
bool operator ()(shared_ptr<Derived> const &that) const
{
return this->self_ != that.get();
}
private:
enable_reference_tracking<Derived> *self_;
};
///////////////////////////////////////////////////////////////////////////////
// swap without bringing in std::swap -- must be found by ADL.
template<typename T>
void adl_swap(T &t1, T &t2)
{
swap(t1, t2);
}
///////////////////////////////////////////////////////////////////////////////
// enable_reference_tracking
// inherit from this type to enable reference tracking for a type. You can
// then use tracking_ptr (below) as a holder for derived objects.
//
template<typename Derived>
struct enable_reference_tracking
{
typedef std::set<shared_ptr<Derived> > references_type;
typedef std::set<weak_ptr<Derived> > dependents_type;
void tracking_copy(Derived const &that)
{
if(&this->derived_() != &that)
{
this->raw_copy_(that);
this->tracking_update();
}
}
void tracking_clear()
{
this->raw_copy_(Derived());
}
// called automatically as a result of a tracking_copy(). Must be called explicitly
// if you change the references without calling tracking_copy().
void tracking_update()
{
// add "this" as a dependency to all the references
this->update_references_();
// notify our dependencies that we have new references
this->update_dependents_();
}
void track_reference(enable_reference_tracking<Derived> &that)
{
// avoid some unbounded memory growth in certain circumstances by
// opportunistically removing stale dependencies from "that"
that.purge_stale_deps_();
// add "that" as a reference
this->refs_.insert(that.self_);
// also inherit that's references
this->refs_.insert(that.refs_.begin(), that.refs_.end());
}
long use_count() const
{
return this->cnt_;
}
void add_ref()
{
++this->cnt_;
}
void release()
{
BOOST_ASSERT(0 < this->cnt_);
if(0 == --this->cnt_)
{
this->refs_.clear();
this->self_.reset();
}
}
//{{AFX_DEBUG
#ifdef BOOST_XPRESSIVE_DEBUG_TRACKING_POINTER
friend std::ostream &operator <<(std::ostream &sout, enable_reference_tracking<Derived> const &that)
{
that.dump_(sout);
return sout;
}
#endif
//}}AFX_DEBUG
protected:
enable_reference_tracking()
: refs_()
, deps_()
, self_()
, cnt_(0)
{
}
enable_reference_tracking(enable_reference_tracking<Derived> const &that)
: refs_()
, deps_()
, self_()
, cnt_(0)
{
this->operator =(that);
}
enable_reference_tracking<Derived> &operator =(enable_reference_tracking<Derived> const &that)
{
references_type(that.refs_).swap(this->refs_);
return *this;
}
void swap(enable_reference_tracking<Derived> &that)
{
this->refs_.swap(that.refs_);
}
private:
friend struct tracking_ptr<Derived>;
Derived &derived_()
{
return *static_cast<Derived *>(this);
}
void raw_copy_(Derived that)
{
detail::adl_swap(this->derived_(), that);
}
bool has_deps_() const
{
return !this->deps_.empty();
}
void update_references_()
{
typename references_type::iterator cur = this->refs_.begin();
typename references_type::iterator end = this->refs_.end();
for(; cur != end; ++cur)
{
// for each reference, add this as a dependency
(*cur)->track_dependency_(*this);
}
}
void update_dependents_()
{
// called whenever this regex object changes (i.e., is assigned to). it walks
// the list of dependent regexes and updates *their* lists of references,
// thereby spreading out the reference counting responsibility evenly.
weak_iterator<Derived> cur(this->deps_.begin(), &this->deps_);
weak_iterator<Derived> end(this->deps_.end(), &this->deps_);
for(; cur != end; ++cur)
{
(*cur)->track_reference(*this);
}
}
void track_dependency_(enable_reference_tracking<Derived> &dep)
{
if(this == &dep) // never add ourself as a dependency
return;
// add dep as a dependency
this->deps_.insert(dep.self_);
filter_self<Derived> not_self(this);
weak_iterator<Derived> begin(dep.deps_.begin(), &dep.deps_);
weak_iterator<Derived> end(dep.deps_.end(), &dep.deps_);
// also inherit dep's dependencies
this->deps_.insert(
make_filter_iterator(not_self, begin, end)
, make_filter_iterator(not_self, end, end)
);
}
void purge_stale_deps_()
{
weak_iterator<Derived> cur(this->deps_.begin(), &this->deps_);
weak_iterator<Derived> end(this->deps_.end(), &this->deps_);
for(; cur != end; ++cur)
;
}
//{{AFX_DEBUG
#ifdef BOOST_XPRESSIVE_DEBUG_TRACKING_POINTER
void dump_(std::ostream &sout) const;
#endif
//}}AFX_DEBUG
references_type refs_;
dependents_type deps_;
shared_ptr<Derived> self_;
boost::detail::atomic_count cnt_;
};
template<typename Derived>
inline void intrusive_ptr_add_ref(enable_reference_tracking<Derived> *p)
{
p->add_ref();
}
template<typename Derived>
inline void intrusive_ptr_release(enable_reference_tracking<Derived> *p)
{
p->release();
}
//{{AFX_DEBUG
#ifdef BOOST_XPRESSIVE_DEBUG_TRACKING_POINTER
///////////////////////////////////////////////////////////////////////////////
// dump_
//
template<typename Derived>
inline void enable_reference_tracking<Derived>::dump_(std::ostream &sout) const
{
shared_ptr<Derived> this_ = this->self_;
sout << "0x" << (void*)this << " cnt=" << this_.use_count()-1 << " refs={";
typename references_type::const_iterator cur1 = this->refs_.begin();
typename references_type::const_iterator end1 = this->refs_.end();
for(; cur1 != end1; ++cur1)
{
sout << "0x" << (void*)&**cur1 << ',';
}
sout << "} deps={";
typename dependents_type::const_iterator cur2 = this->deps_.begin();
typename dependents_type::const_iterator end2 = this->deps_.end();
for(; cur2 != end2; ++cur2)
{
// ericne, 27/nov/05: CW9_4 doesn't like if(shared_ptr x = y)
shared_ptr<Derived> dep = cur2->lock();
if(dep.get())
{
sout << "0x" << (void*)&*dep << ',';
}
}
sout << '}';
}
#endif
//}}AFX_DEBUG
///////////////////////////////////////////////////////////////////////////////
// tracking_ptr
// holder for a reference-tracked type. Does cycle-breaking, lazy initialization
// and copy-on-write. TODO: implement move semantics.
//
template<typename Type>
struct tracking_ptr
{
BOOST_MPL_ASSERT((is_base_and_derived<enable_reference_tracking<Type>, Type>));
typedef Type element_type;
tracking_ptr()
: impl_()
{
}
tracking_ptr(tracking_ptr<element_type> const &that)
: impl_()
{
this->operator =(that);
}
tracking_ptr<element_type> &operator =(tracking_ptr<element_type> const &that)
{
// Note: the copy-and-swap idiom doesn't work here if has_deps_()==true
// because it invalidates references to the element_type object.
if(this != &that)
{
if(that)
{
if(that.has_deps_() || this->has_deps_())
{
this->fork_(); // deep copy, forks data if necessary
this->impl_->tracking_copy(*that);
}
else
{
this->impl_ = that.impl_; // shallow, copy-on-write
}
}
else if(*this)
{
this->impl_->tracking_clear();
}
}
return *this;
}
// NOTE: this does *not* do tracking. Can't provide a non-throwing swap that tracks references
void swap(tracking_ptr<element_type> &that) // throw()
{
this->impl_.swap(that.impl_);
}
// calling this forces this->impl_ to fork.
shared_ptr<element_type> const &get() const
{
if(intrusive_ptr<element_type> impl = this->fork_())
{
this->impl_->tracking_copy(*impl);
}
return this->impl_->self_;
}
#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530)
typedef bool unspecified_bool_type;
#else
typedef typename intrusive_ptr<element_type>::unspecified_bool_type unspecified_bool_type;
#endif
// smart-pointer operators
operator unspecified_bool_type() const
{
return this->impl_;
}
bool operator !() const
{
return !this->impl_;
}
// Since this does not un-share the data, it returns a ptr-to-const
element_type const *operator ->() const
{
return get_pointer(this->impl_);
}
// Since this does not un-share the data, it returns a ref-to-const
element_type const &operator *() const
{
return *this->impl_;
}
private:
// calling this forces impl_ to fork.
intrusive_ptr<element_type> fork_() const
{
intrusive_ptr<element_type> impl;
if(!this->impl_ || 1 != this->impl_->use_count())
{
impl = this->impl_;
BOOST_ASSERT(!this->has_deps_());
shared_ptr<element_type> simpl(new element_type);
this->impl_ = get_pointer(simpl->self_ = simpl);
}
return impl;
}
// does anybody have a dependency on us?
bool has_deps_() const
{
return this->impl_ && this->impl_->has_deps_();
}
// mutable to allow lazy initialization
mutable intrusive_ptr<element_type> impl_;
};
}}} // namespace boost::xpressive::detail
#endif

View File

@@ -0,0 +1,145 @@
///////////////////////////////////////////////////////////////////////////////
// traits_utils.hpp
//
// Copyright 2008 Eric Niebler. 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_XPRESSIVE_DETAIL_UTILITY_TRAITS_UTILS_HPP_EAN_10_04_2005
#define BOOST_XPRESSIVE_DETAIL_UTILITY_TRAITS_UTILS_HPP_EAN_10_04_2005
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
# pragma warning(push)
# pragma warning(disable : 4100) // unreferenced formal parameter
#endif
#include <string>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/iterator/transform_iterator.hpp>
#include <boost/xpressive/detail/utility/algorithm.hpp>
namespace boost { namespace xpressive { namespace detail
{
///////////////////////////////////////////////////////////////////////////////
// char_cast
//
template<typename ToChar, typename FromChar, typename Traits>
inline ToChar
char_cast(FromChar from, Traits const &, typename enable_if<is_same<ToChar, FromChar> >::type * = 0)
{
return from;
}
template<typename ToChar, typename FromChar, typename Traits>
inline ToChar
char_cast(FromChar from, Traits const &tr, typename disable_if<is_same<ToChar, FromChar> >::type * = 0)
{
BOOST_MPL_ASSERT((is_same<FromChar, char>));
return tr.widen(from);
}
///////////////////////////////////////////////////////////////////////////////
// widen_fun
//
template<typename Traits>
struct widen_fun
{
typedef typename Traits::char_type result_type;
explicit widen_fun(Traits const &tr)
: traits_(tr)
{}
result_type operator()(char ch) const
{
return this->traits_.widen(ch);
}
Traits const &traits_;
};
///////////////////////////////////////////////////////////////////////////////
// string_cast_
//
template<
typename To
, typename From
, typename ToChar = typename detail::range_data<To>::type
, typename FromChar = typename detail::range_data<From>::type
>
struct string_cast_
{
BOOST_MPL_ASSERT((is_same<FromChar, char>));
typedef To const result_type;
template<typename Traits>
result_type operator()(From const &from, Traits const &tr) const
{
widen_fun<Traits> widen(tr);
To to(
boost::make_transform_iterator(detail::data_begin(from), widen)
, boost::make_transform_iterator(detail::data_end(from), widen)
);
return to;
}
};
template<typename To, typename From, typename Char>
struct string_cast_<To, From, Char, Char>
{
typedef To const result_type;
template<typename Traits>
result_type operator()(From const &from, Traits const &) const
{
To to(detail::data_begin(from), detail::data_end(from));
return to;
}
};
template<typename From, typename Char>
struct string_cast_<From, From, Char, Char>
{
typedef From const &result_type;
template<typename Traits>
result_type operator()(From const &from, Traits const &) const
{
return from;
}
};
///////////////////////////////////////////////////////////////////////////////
// string_cast
//
template<typename To, typename From, typename Traits>
typename string_cast_<To, From>::result_type
string_cast(From const &from, Traits const &tr)
{
return string_cast_<To, From>()(from, tr);
}
///////////////////////////////////////////////////////////////////////////////
// translate
//
template<typename Char, typename Traits>
inline Char translate(Char ch, Traits const &tr, mpl::false_) // case-sensitive
{
return tr.translate(ch);
}
template<typename Char, typename Traits>
inline Char translate(Char ch, Traits const &tr, mpl::true_) // case-insensitive
{
return tr.translate_nocase(ch);
}
}}} // namespace boost::xpressive::detail
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma warning(pop)
#endif
#endif

View File

@@ -0,0 +1,94 @@
///////////////////////////////////////////////////////////////////////////////
// width.hpp
//
// Copyright 2008 Eric Niebler. 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_XPRESSIVE_DETAIL_UTILITY_WIDTH_HPP_EAN_04_07_2006
#define BOOST_XPRESSIVE_DETAIL_UTILITY_WIDTH_HPP_EAN_04_07_2006
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include <climits> // for INT_MAX
#include <boost/mpl/size_t.hpp>
namespace boost { namespace xpressive { namespace detail
{
typedef mpl::size_t<INT_MAX / 2 - 1> unknown_width;
struct width;
bool is_unknown(width const &that);
///////////////////////////////////////////////////////////////////////////////
// width
struct width
{
width(std::size_t val = 0)
: value_(val)
{
}
bool operator !() const
{
return !this->value_;
}
width &operator +=(width const &that)
{
this->value_ =
!is_unknown(*this) && !is_unknown(that)
? this->value_ + that.value_
: unknown_width();
return *this;
}
width &operator |=(width const &that)
{
this->value_ =
this->value_ == that.value_
? this->value_
: unknown_width();
return *this;
}
std::size_t value() const
{
return this->value_;
}
private:
std::size_t value_;
};
inline bool is_unknown(width const &that)
{
return unknown_width::value == that.value();
}
inline bool operator ==(width const &left, width const &right)
{
return left.value() == right.value();
}
inline bool operator !=(width const &left, width const &right)
{
return left.value() != right.value();
}
inline width operator +(width left, width const &right)
{
return left += right;
}
inline width operator |(width left, width const &right)
{
return left |= right;
}
}}} // namespace boost::xpressive::detail
#endif