diff options
author | Anas Nashif <anas.nashif@intel.com> | 2012-10-30 12:57:26 -0700 |
---|---|---|
committer | Anas Nashif <anas.nashif@intel.com> | 2012-10-30 12:57:26 -0700 |
commit | 1a78a62555be32868418fe52f8e330c9d0f95d5a (patch) | |
tree | d3765a80e7d3b9640ec2e930743630cd6b9fce2b /boost/spirit/home/classic | |
download | boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.tar.gz boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.tar.bz2 boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.zip |
Imported Upstream version 1.49.0upstream/1.49.0
Diffstat (limited to 'boost/spirit/home/classic')
195 files changed, 49694 insertions, 0 deletions
diff --git a/boost/spirit/home/classic/actor.hpp b/boost/spirit/home/classic/actor.hpp new file mode 100644 index 0000000000..706099414d --- /dev/null +++ b/boost/spirit/home/classic/actor.hpp @@ -0,0 +1,113 @@ +/*============================================================================= + Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com) + 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_ACTOR_HPP +#define BOOST_SPIRIT_ACTOR_HPP + +#include <boost/spirit/home/classic/version.hpp> + +/////////////////////////////////////////////////////////////////////////////// +// +// Actors documentation and convention +// +// Actors +// +// Actors are predefined semantic action functors. They are used to do an +// action on the parse result if the parser has had a successful match. An +// example of actor is the append_actor described in the Spirit +// documentation. +// +// The action takes place through a call to the () operator: single argument +// () operator call for character parsers and two argument (first,last) call +// for phrase parsers. Actors should implement at least one of the two () +// operator. +// +// Actor instances are not created direcly since they usually involve a +// number of template parameters. Instead generator functions ("helper +// functions") are provided to generate actors according to their arguments. +// All helper functions have the "_a" suffix. For example, append_actor is +// created using the append_a function. +// +// Policy holder actors and policy actions +// +// A lot of actors need to store reference to one or more objects. For +// example, actions on container need to store a reference to the container. +// Therefore, this kind of actor have been broken down into +// +// - a action policy that does the action (act method), +// - a policy holder actor that stores the references and feeds the act +// method. +// +// Policy holder actors +// +// Policy holder have the following naming convention: +// <member>_ >> *<member> >> !value >> actor +// where member are the policy stored member, they can be of type: +// +// - ref, a reference, +// - const_ref, a const reference, +// - value, by value, +// - empty, no stored members +// - !value states if the policy uses the parse result or not. +// +// The available policy holder are enumerated below: +// +// - empty_actor, nothing stored, feeds parse result +// - value_actor, 1 object stored by value, feeds value +// - ref_actor, 1 reference stored, feeds ref +// - ref_value_actor, 1 reference stored, feeds ref and parse result +// +// Doc. convention +// +// - ref is a reference to an object stored in a policy holder actor, +// - value_ref,value1_ref, value2_ref are a const reference stored in a +// policy holder actor, +// - value is the parse result in the single argument () operator, +// - first,last are the parse result in the two argument () operator +// +// Actors (generator functions) and quick description +// +// - assign_a(ref) assign parse result to ref +// - assign_a(ref, value_ref) assign value_ref to ref +// - increment_a(ref) increment ref +// - decrement_a(ref) decrement ref +// - push_back_a(ref) push back the parse result in ref +// - push_back_a(ref, value_ref) push back value_ref in ref +// - push_front_a(ref) push front the parse result in ref +// - push_front_a(ref, value_ref) push front value_ref in ref +// - insert_key_a(ref,value_ref) insert value_ref in ref using the +// parse result as key +// - insert_at_a(ref, key_ref) insert the parse result in ref at key_ref +// - insert_at_a(ref, key_ref insert value_ref in ref at key_ref +// , value_ref) +// - assign_key_a(ref, value_ref) assign value_ref in ref using the +// parse result as key +// - erase_a(ref, key) erase data at key from ref +// - clear_a(ref) clears ref +// - swap_a(aref, bref) swaps aref and bref +// +/////////////////////////////////////////////////////////////////////////////// + +#include <boost/spirit/home/classic/actor/ref_actor.hpp> +#include <boost/spirit/home/classic/actor/ref_value_actor.hpp> +#include <boost/spirit/home/classic/actor/ref_const_ref_actor.hpp> +#include <boost/spirit/home/classic/actor/ref_const_ref_value_actor.hpp> +#include <boost/spirit/home/classic/actor/ref_const_ref_const_ref_a.hpp> + +#include <boost/spirit/home/classic/actor/assign_actor.hpp> +#include <boost/spirit/home/classic/actor/clear_actor.hpp> +#include <boost/spirit/home/classic/actor/increment_actor.hpp> +#include <boost/spirit/home/classic/actor/decrement_actor.hpp> +#include <boost/spirit/home/classic/actor/push_back_actor.hpp> +#include <boost/spirit/home/classic/actor/push_front_actor.hpp> +#include <boost/spirit/home/classic/actor/erase_actor.hpp> +#include <boost/spirit/home/classic/actor/insert_key_actor.hpp> +#include <boost/spirit/home/classic/actor/insert_at_actor.hpp> +#include <boost/spirit/home/classic/actor/assign_key_actor.hpp> +#include <boost/spirit/home/classic/actor/swap_actor.hpp> + +#endif diff --git a/boost/spirit/home/classic/actor/assign_actor.hpp b/boost/spirit/home/classic/actor/assign_actor.hpp new file mode 100644 index 0000000000..94551308d8 --- /dev/null +++ b/boost/spirit/home/classic/actor/assign_actor.hpp @@ -0,0 +1,100 @@ +/*============================================================================= + Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com) + 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_ACTOR_ASSIGN_ACTOR_HPP +#define BOOST_SPIRIT_ACTOR_ASSIGN_ACTOR_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/actor/ref_value_actor.hpp> +#include <boost/spirit/home/classic/actor/ref_const_ref_actor.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // Summary: + // A semantic action policy that applies the assignement operator. + // (This doc uses convention available in actors.hpp) + // + // Actions (what it does): + // ref = value; + // ref = T(first,last); + // ref = value_ref; + // + // Policy name: + // assign_action + // + // Policy holder, corresponding helper method: + // ref_value_actor, assign_a( ref ); + // ref_const_ref_actor, assign_a( ref, value_ref ); + // + // () operators: both + // + // See also ref_value_actor and ref_const_ref_actor for more details. + /////////////////////////////////////////////////////////////////////////// + struct assign_action + { + template< + typename T, + typename ValueT + > + void act(T& ref_, ValueT const& value_) const + { + ref_ = value_; + } + template< + typename T, + typename IteratorT + > + void act( + T& ref_, + IteratorT const& first_, + IteratorT const& last_ + ) const + { + typedef T value_type; +#ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS + value_type value(first_,last_); +#else + value_type value; + std::copy(first_, last_, std::inserter(value, value.end())); +#endif + ref_ = value; + } + }; + + // Deprecated. Please use assign_a + template<typename T> + inline ref_value_actor<T,assign_action> assign(T& ref_) + { + return ref_value_actor<T,assign_action>(ref_); + } + + template<typename T> + inline ref_value_actor<T,assign_action> assign_a(T& ref_) + { + return ref_value_actor<T,assign_action>(ref_); + } + + template< + typename T, + typename ValueT + > + inline ref_const_ref_actor<T,ValueT,assign_action> assign_a( + T& ref_, + ValueT const& value_ + ) + { + return ref_const_ref_actor<T,ValueT,assign_action>(ref_,value_); + } + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} + +#endif diff --git a/boost/spirit/home/classic/actor/assign_key_actor.hpp b/boost/spirit/home/classic/actor/assign_key_actor.hpp new file mode 100644 index 0000000000..f6711d30fb --- /dev/null +++ b/boost/spirit/home/classic/actor/assign_key_actor.hpp @@ -0,0 +1,96 @@ +/*============================================================================= + Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com) + 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_ACTOR_ASSIGN_KEY_ACTOR_HPP +#define BOOST_SPIRIT_ACTOR_ASSIGN_KEY_ACTOR_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/actor/ref_const_ref_value_actor.hpp> +#include <boost/spirit/home/classic/actor/ref_const_ref_const_ref_a.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + struct assign_key_action + { + template< + typename T, + typename ValueT, + typename KeyT + > + void act(T& ref_, ValueT const& value_, KeyT const& key_) const + { + ref_[ key_ ] = value_; + } + + template< + typename T, + typename ValueT, + typename IteratorT + > + void act( + T& ref_, + ValueT const& value_, + IteratorT const& first_, + IteratorT const& last_ + ) const + { + typedef typename T::key_type key_type; + key_type key(first_,last_); + + ref_[key] = value_; + } + }; + + template< + typename T, + typename ValueT + > + inline ref_const_ref_value_actor<T,ValueT,assign_key_action> + assign_key_a(T& ref_, ValueT const& value_) + { + return ref_const_ref_value_actor<T,ValueT,assign_key_action>( + ref_, + value_ + ); + } + + template< + typename T, + typename ValueT, + typename KeyT + > + inline ref_const_ref_const_ref_actor< + T, + ValueT, + KeyT, + assign_key_action + > + assign_key_a( + T& ref_, + ValueT const& value_, + KeyT const& key_ + ) + { + return ref_const_ref_const_ref_actor< + T, + ValueT, + KeyT, + assign_key_action + >( + ref_, + value_, + key_ + ); + } + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} + +#endif diff --git a/boost/spirit/home/classic/actor/clear_actor.hpp b/boost/spirit/home/classic/actor/clear_actor.hpp new file mode 100644 index 0000000000..9af670dcc6 --- /dev/null +++ b/boost/spirit/home/classic/actor/clear_actor.hpp @@ -0,0 +1,61 @@ +/*============================================================================= + Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com) + 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_ACTOR_CLEAR_ACTOR_HPP +#define BOOST_SPIRIT_ACTOR_CLEAR_ACTOR_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/actor/ref_actor.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // Summary: + // A semantic action policy that calls clear method. + // (This doc uses convention available in actors.hpp) + // + // Actions (what it does): + // ref.clear(); + // + // Policy name: + // clear_action + // + // Policy holder, corresponding helper method: + // ref_actor, clear_a( ref ); + // + // () operators: both. + // + // See also ref_actor for more details. + /////////////////////////////////////////////////////////////////////////// + struct clear_action + { + template< + typename T + > + void act(T& ref_) const + { + ref_.clear(); + } + }; + + /////////////////////////////////////////////////////////////////////////// + // helper method that creates a and_assign_actor. + /////////////////////////////////////////////////////////////////////////// + template<typename T> + inline ref_actor<T,clear_action> clear_a(T& ref_) + { + return ref_actor<T,clear_action>(ref_); + } + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} + +#endif + diff --git a/boost/spirit/home/classic/actor/decrement_actor.hpp b/boost/spirit/home/classic/actor/decrement_actor.hpp new file mode 100644 index 0000000000..99cdf35d7f --- /dev/null +++ b/boost/spirit/home/classic/actor/decrement_actor.hpp @@ -0,0 +1,60 @@ +/*============================================================================= + Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com) + 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_ACTOR_DECREMENT_ACTOR_HPP +#define BOOST_SPIRIT_ACTOR_DECREMENT_ACTOR_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/actor/ref_actor.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // Summary: + // A semantic action policy that calls the -- operator on a reference. + // (This doc uses convention available in actors.hpp) + // + // Actions: + // --ref; + // + // Policy name: + // decrement_action + // + // Policy holder, corresponding helper method: + // ref_actor, decrement_a( ref ); + // + // () operators: both. + // + // See also ref_actor for more details. + /////////////////////////////////////////////////////////////////////////// + struct decrement_action + { + template< + typename T + > + void act(T& ref_) const + { + --ref_; + } + }; + + /////////////////////////////////////////////////////////////////////////// + // helper method that creates a and_assign_actor. + /////////////////////////////////////////////////////////////////////////// + template<typename T> + inline ref_actor<T,decrement_action> decrement_a(T& ref_) + { + return ref_actor<T,decrement_action>(ref_); + } + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} + +#endif diff --git a/boost/spirit/home/classic/actor/erase_actor.hpp b/boost/spirit/home/classic/actor/erase_actor.hpp new file mode 100644 index 0000000000..dca1b40435 --- /dev/null +++ b/boost/spirit/home/classic/actor/erase_actor.hpp @@ -0,0 +1,89 @@ +/*============================================================================= + Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com) + 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_ACTOR_ERASE_ACTOR_HPP +#define BOOST_SPIRIT_ACTOR_ERASE_ACTOR_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/actor/ref_value_actor.hpp> +#include <boost/spirit/home/classic/actor/ref_const_ref_actor.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // Summary: + // A semantic action policy that calss the erase method. + // (This doc uses convention available in actors.hpp) + // + // Actions (what it does): + // ref.erase( value ); + // ref.erase( T::key_type(first,last) ); + // ref.erase( key_ref ); + // + // Policy name: + // erase_action + // + // Policy holder, corresponding helper method: + // ref_value_actor, erase_a( ref ); + // ref_const_ref_actor, erase_a( ref, key_ref ); + // + // () operators: both + // + // See also ref_value_actor and ref_const_ref_actor for more details. + /////////////////////////////////////////////////////////////////////////// + struct erase_action + { + template< + typename T, + typename KeyT + > + void act(T& ref_, KeyT const& key_) const + { + ref_.erase(key_); + } + template< + typename T, + typename IteratorT + > + void act( + T& ref_, + IteratorT const& first_, + IteratorT const& last_ + ) const + { + typedef typename T::key_type key_type; + key_type key(first_,last_); + + ref_.erase(key); + } + }; + + template<typename T> + inline ref_value_actor<T,erase_action> erase_a(T& ref_) + { + return ref_value_actor<T,erase_action>(ref_); + } + + template< + typename T, + typename KeyT + > + inline ref_const_ref_actor<T,KeyT,erase_action> erase_a( + T& ref_, + KeyT const& key_ + ) + { + return ref_const_ref_actor<T,KeyT,erase_action>(ref_,key_); + } + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} + +#endif diff --git a/boost/spirit/home/classic/actor/increment_actor.hpp b/boost/spirit/home/classic/actor/increment_actor.hpp new file mode 100644 index 0000000000..776568887e --- /dev/null +++ b/boost/spirit/home/classic/actor/increment_actor.hpp @@ -0,0 +1,60 @@ +/*============================================================================= + Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com) + 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_ACTOR_INCREMENT_ACTOR_HPP +#define BOOST_SPIRIT_ACTOR_INCREMENT_ACTOR_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/actor/ref_actor.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // Summary: + // A semantic action policy that calls the ++ operator on a reference. + // (This doc uses convention available in actors.hpp) + // + // Actions: + // ++ref; + // + // Policy name: + // increment_action + // + // Policy holder, corresponding helper method: + // ref_actor, increment_a( ref ); + // + // () operators: both. + // + // See also ref_actor for more details. + /////////////////////////////////////////////////////////////////////////// + struct increment_action + { + template< + typename T + > + void act(T& ref_) const + { + ++ref_; + } + }; + + /////////////////////////////////////////////////////////////////////////// + // helper method that creates a increment_actor. + /////////////////////////////////////////////////////////////////////////// + template<typename T> + inline ref_actor<T,increment_action> increment_a(T& ref_) + { + return ref_actor<T,increment_action>(ref_); + } + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} + +#endif diff --git a/boost/spirit/home/classic/actor/insert_at_actor.hpp b/boost/spirit/home/classic/actor/insert_at_actor.hpp new file mode 100644 index 0000000000..5dd7497232 --- /dev/null +++ b/boost/spirit/home/classic/actor/insert_at_actor.hpp @@ -0,0 +1,121 @@ +/*============================================================================= + Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com) + 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_ACTOR_INSERT_AT_ACTOR_HPP +#define BOOST_SPIRIT_ACTOR_INSERT_AT_ACTOR_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/actor/ref_const_ref_value_actor.hpp> +#include <boost/spirit/home/classic/actor/ref_const_ref_const_ref_a.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // Summary: + // A semantic action policy that insert data into an associative + // container using a const reference to a key. + // (This doc uses convention available in actors.hpp) + // + // Actions (what it does): + // ref.insert( T::value_type(key_ref,value) ); + // ref.insert( T::value_type(key_ref, T::mapped_type(first,last)));; + // ref.insert( T::value_type(key_ref,value_ref) ); + // + // Policy name: + // insert_at_action + // + // Policy holder, corresponding helper method: + // ref_const_ref_value_actor, insert_at_a( ref, key_ref ); + // ref_const_ref_const_ref_actor, insert_a( ref, key_ref, value_ref ); + // + // () operators: both + // + // See also ref_const_ref_value_actor and ref_const_ref_const_ref_actor + // for more details. + /////////////////////////////////////////////////////////////////////////// + struct insert_at_action + { + template< + typename T, + typename ReferentT, + typename ValueT + > + void act( + T& ref_, + ReferentT const& key_, + ValueT const& value_ + ) const + { + typedef typename T::value_type value_type; + ref_.insert( value_type(key_, value_) ); + } + + template< + typename T, + typename ReferentT, + typename IteratorT + > + void act( + T& ref_, + ReferentT const& key_, + IteratorT const& first_, + IteratorT const& last_ + ) const + { + typedef typename T::mapped_type mapped_type; + typedef typename T::value_type value_type; + + mapped_type value(first_,last_); + value_type key_value(key_, value); + ref_.insert( key_value ); + } + }; + + template< + typename T, + typename ReferentT + > + inline ref_const_ref_value_actor<T,ReferentT,insert_at_action> + insert_at_a( + T& ref_, + ReferentT const& key_ + ) + { + return ref_const_ref_value_actor< + T, + ReferentT, + insert_at_action + >(ref_,key_); + } + + template< + typename T, + typename ReferentT, + typename ValueT + > + inline ref_const_ref_const_ref_actor<T,ReferentT,ValueT,insert_at_action> + insert_at_a( + T& ref_, + ReferentT const& key_, + ValueT const& value_ + ) + { + return ref_const_ref_const_ref_actor< + T, + ReferentT, + ValueT, + insert_at_action + >(ref_,key_,value_); + } + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} + +#endif diff --git a/boost/spirit/home/classic/actor/insert_key_actor.hpp b/boost/spirit/home/classic/actor/insert_key_actor.hpp new file mode 100644 index 0000000000..859a8d8363 --- /dev/null +++ b/boost/spirit/home/classic/actor/insert_key_actor.hpp @@ -0,0 +1,97 @@ +/*============================================================================= + Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com) + 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_ACTOR_INSERT_KEY_ACTOR_HPP +#define BOOST_SPIRIT_ACTOR_INSERT_KEY_ACTOR_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/actor/ref_const_ref_value_actor.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // Summary: + // A semantic action policy that insert data into an associative + // container using a const reference to data. + // (This doc uses convention available in actors.hpp) + // + // Actions (what it does): + // ref.insert( T::value_type(value,value_ref) ); + // ref.insert( T::value_type(T::key_type(first,last), value_ref));; + // + // Policy name: + // insert_key_action + // + // Policy holder, corresponding helper method: + // ref_const_ref_value_actor, insert_key_a( ref, value_ref ); + // + // () operators: both + // + // See also ref_const_ref_value_actor for more details. + /////////////////////////////////////////////////////////////////////////// + struct insert_key_action + { + template< + typename T, + typename ValueT, + typename ReferentT + > + void act( + T& ref_, + ValueT const& value_, + ReferentT const& key_ + ) const + { + typedef typename T::value_type value_type; + value_type key_value(key_, value_); + ref_.insert( key_value ); + } + + template< + typename T, + typename ValueT, + typename IteratorT + > + void act( + T& ref_, + ValueT const& value_, + IteratorT const& first_, + IteratorT const& last_ + ) const + { + typedef typename T::key_type key_type; + typedef typename T::value_type value_type; + + key_type key(first_,last_); + value_type key_value(key, value_); + ref_.insert( key_value ); + } + }; + + template< + typename T, + typename ValueT + > + inline ref_const_ref_value_actor<T,ValueT,insert_key_action> insert_key_a( + T& ref_, + ValueT const& value_ + ) + { + return ref_const_ref_value_actor< + T, + ValueT, + insert_key_action + >(ref_,value_); + } + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} + +#endif diff --git a/boost/spirit/home/classic/actor/push_back_actor.hpp b/boost/spirit/home/classic/actor/push_back_actor.hpp new file mode 100644 index 0000000000..cbdd790709 --- /dev/null +++ b/boost/spirit/home/classic/actor/push_back_actor.hpp @@ -0,0 +1,101 @@ +/*============================================================================= + Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com) + 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_ACTOR_PUSH_BACK_ACTOR_HPP +#define BOOST_SPIRIT_ACTOR_PUSH_BACK_ACTOR_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/actor/ref_value_actor.hpp> +#include <boost/spirit/home/classic/actor/ref_const_ref_actor.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // Summary: + // + // A semantic action policy that appends a value to the back of a + // container. + // (This doc uses convention available in actors.hpp) + // + // Actions (what it does and what ref, value_ref must support): + // ref.push_back( value ); + // ref.push_back( T::value_type(first,last) ); + // ref.push_back( value_ref ); + // + // Policy name: + // push_back_action + // + // Policy holder, corresponding helper method: + // ref_value_actor, push_back_a( ref ); + // ref_const_ref_actor, push_back_a( ref, value_ref ); + // + // () operators: both + // + // See also ref_value_actor and ref_const_ref_actor for more details. + /////////////////////////////////////////////////////////////////////////// + struct push_back_action + { + template< + typename T, + typename ValueT + > + void act(T& ref_, ValueT const& value_) const + { + ref_.push_back( value_ ); + } + template< + typename T, + typename IteratorT + > + void act( + T& ref_, + IteratorT const& first_, + IteratorT const& last_ + ) const + { + typedef typename T::value_type value_type; + value_type value(first_,last_); + + ref_.push_back( value ); + } + }; + +// Deprecated interface. Use push_back_a + template<typename T> + inline ref_value_actor<T,push_back_action> + append(T& ref_) + { + return ref_value_actor<T,push_back_action>(ref_); + } + + template<typename T> + inline ref_value_actor<T,push_back_action> + push_back_a(T& ref_) + { + return ref_value_actor<T,push_back_action>(ref_); + } + + template< + typename T, + typename ValueT + > + inline ref_const_ref_actor<T,ValueT,push_back_action> + push_back_a( + T& ref_, + ValueT const& value_ + ) + { + return ref_const_ref_actor<T,ValueT,push_back_action>(ref_,value_); + } + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} + +#endif diff --git a/boost/spirit/home/classic/actor/push_front_actor.hpp b/boost/spirit/home/classic/actor/push_front_actor.hpp new file mode 100644 index 0000000000..43cb183513 --- /dev/null +++ b/boost/spirit/home/classic/actor/push_front_actor.hpp @@ -0,0 +1,91 @@ +/*============================================================================= + Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com) + 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_ACTOR_PUSH_FRONT_ACTOR_HPP +#define BOOST_SPIRIT_ACTOR_PUSH_FRONT_ACTOR_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/actor/ref_value_actor.hpp> +#include <boost/spirit/home/classic/actor/ref_const_ref_actor.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // Summary: + // + // A semantic action policy that appends a value to the front of a + // container. + // (This doc uses convention available in actors.hpp) + // + // Actions (what it does and what ref, value_ref must support): + // ref.push_front( value ); + // ref.push_front( T::value_type(first,last) ); + // ref.push_front( value_ref ); + // + // Policy name: + // push_front_action + // + // Policy holder, corresponding helper method: + // ref_value_actor, push_front_a( ref ); + // ref_const_ref_actor, push_front_a( ref, value_ref ); + // + // () operators: both + // + // See also ref_value_actor and ref_const_ref_actor for more details. + /////////////////////////////////////////////////////////////////////////// + struct push_front_action + { + template< + typename T, + typename ValueT + > + void act(T& ref_, ValueT const& value_) const + { + ref_.push_front( value_ ); + } + template< + typename T, + typename IteratorT + > + void act( + T& ref_, + IteratorT const& first_, + IteratorT const& last_ + ) const + { + typedef typename T::value_type value_type; + value_type value(first_,last_); + + ref_.push_front( value ); + } + }; + + template<typename T> + inline ref_value_actor<T,push_front_action> push_front_a(T& ref_) + { + return ref_value_actor<T,push_front_action>(ref_); + } + + template< + typename T, + typename ValueT + > + inline ref_const_ref_actor<T,ValueT,push_front_action> push_front_a( + T& ref_, + ValueT const& value_ + ) + { + return ref_const_ref_actor<T,ValueT,push_front_action>(ref_,value_); + } + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} + +#endif diff --git a/boost/spirit/home/classic/actor/ref_actor.hpp b/boost/spirit/home/classic/actor/ref_actor.hpp new file mode 100644 index 0000000000..4cf7a47c07 --- /dev/null +++ b/boost/spirit/home/classic/actor/ref_actor.hpp @@ -0,0 +1,70 @@ +/*============================================================================= + Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com) + 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_ACTOR_REF_ACTOR_HPP +#define BOOST_SPIRIT_ACTOR_REF_ACTOR_HPP + +#include <boost/spirit/home/classic/namespace.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // Summary: + // A semantic action policy holder. This holder stores a reference to ref, + // act methods are fead with this reference. The parse result is not used + // by this holder. + // + // (This doc uses convention available in actors.hpp) + // + // Constructor: + // ...(T& ref_); + // where ref_ is stored. + // + // Action calls: + // act(ref); + // + // () operators: both + // + /////////////////////////////////////////////////////////////////////////// + template< + typename T, + typename ActionT + > + class ref_actor : public ActionT + { + private: + T& ref; + public: + explicit + ref_actor(T& ref_) + : ref(ref_){} + + + template<typename T2> + void operator()(T2 const& /*val*/) const + { + this->act(ref); // defined in ActionT + } + + + template<typename IteratorT> + void operator()( + IteratorT const& /*first*/, + IteratorT const& /*last*/ + ) const + { + this->act(ref); // defined in ActionT + } + }; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} + +#endif diff --git a/boost/spirit/home/classic/actor/ref_const_ref_actor.hpp b/boost/spirit/home/classic/actor/ref_const_ref_actor.hpp new file mode 100644 index 0000000000..80ee6eb3ad --- /dev/null +++ b/boost/spirit/home/classic/actor/ref_const_ref_actor.hpp @@ -0,0 +1,78 @@ +/*============================================================================= + Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com) + 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_ACTOR_REF_CONST_REF_ACTOR_HPP +#define BOOST_SPIRIT_ACTOR_REF_CONST_REF_ACTOR_HPP + +#include <boost/spirit/home/classic/namespace.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // Summary: + // A semantic action policy holder. This holder stores a reference to ref + // and a const reference to value_ref. + // act methods are feed with ref and value_ref. The parse result is + // not used by this holder. + // + // (This doc uses convention available in actors.hpp) + // + // Constructor: + // ...(T& ref_, ValueT const& value_ref_); + // where ref_ and value_ref_ are stored in the holder. + // + // Action calls: + // act(ref, value_ref); + // + // () operators: both + // + /////////////////////////////////////////////////////////////////////////// + template< + typename T, + typename ValueT, + typename ActionT + > + class ref_const_ref_actor : public ActionT + { + private: + T& ref; + ValueT const& value_ref; + public: + ref_const_ref_actor( + T& ref_, + ValueT const& value_ref_ + ) + : + ref(ref_), + value_ref(value_ref_) + {} + + + template<typename T2> + void operator()(T2 const& /*val*/) const + { + this->act(ref,value_ref); // defined in ActionT + } + + + template<typename IteratorT> + void operator()( + IteratorT const& /*first*/, + IteratorT const& /*last*/ + ) const + { + this->act(ref,value_ref); // defined in ActionT + } + }; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} + +#endif diff --git a/boost/spirit/home/classic/actor/ref_const_ref_const_ref_a.hpp b/boost/spirit/home/classic/actor/ref_const_ref_const_ref_a.hpp new file mode 100644 index 0000000000..2072334d67 --- /dev/null +++ b/boost/spirit/home/classic/actor/ref_const_ref_const_ref_a.hpp @@ -0,0 +1,87 @@ +/*============================================================================= + Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com) + 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_ACTOR_REF_CONST_REF_CONST_REF_ACTOR_HPP +#define BOOST_SPIRIT_ACTOR_REF_CONST_REF_CONST_REF_ACTOR_HPP + +#include <boost/spirit/home/classic/namespace.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // Summary: + // A semantic action policy holder. This holder stores a reference to ref + // , a const reference to value1_ref and a const reference to value2_ref. + // Typically, value1_ref is a key and value2_ref is value for associative + // container operations. + // act methods are feed with ref, value1_ref, value2_ref. The parse result + // is not used by this holder. + // + // (This doc uses convention available in actors.hpp) + // + // Constructor: + // ...( + // T& ref_, + // Value1T const& value1_ref_, + // Value2T const& value2_ref_ ); + // where ref_, value1_ref and value2_ref_ are stored in the holder. + // + // Action calls: + // act(ref, value1_ref, value2_ref); + // + // () operators: both + // + /////////////////////////////////////////////////////////////////////////// + template< + typename T, + typename Value1T, + typename Value2T, + typename ActionT + > + class ref_const_ref_const_ref_actor : public ActionT + { + private: + T& ref; + Value1T const& value1_ref; + Value2T const& value2_ref; + public: + ref_const_ref_const_ref_actor( + T& ref_, + Value1T const& value1_ref_, + Value2T const& value2_ref_ + ) + : + ref(ref_), + value1_ref(value1_ref_), + value2_ref(value2_ref_) + {} + + + template<typename T2> + void operator()(T2 const& /*val*/) const + { + this->act(ref,value1_ref,value2_ref); // defined in ActionT + } + + + template<typename IteratorT> + void operator()( + IteratorT const& /*first*/, + IteratorT const& /*last*/ + ) const + { + this->act(ref,value1_ref,value2_ref); // defined in ActionT + } + }; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} + +#endif diff --git a/boost/spirit/home/classic/actor/ref_const_ref_value_actor.hpp b/boost/spirit/home/classic/actor/ref_const_ref_value_actor.hpp new file mode 100644 index 0000000000..56e5fc98e9 --- /dev/null +++ b/boost/spirit/home/classic/actor/ref_const_ref_value_actor.hpp @@ -0,0 +1,78 @@ +/*============================================================================= + Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com) + 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_ACTOR_REF_CONST_REF_VALUE_ACTOR_HPP +#define BOOST_SPIRIT_ACTOR_REF_CONST_REF_VALUE_ACTOR_HPP + +#include <boost/spirit/home/classic/namespace.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // Summary: + // A semantic action policy holder. This holder stores a reference to ref + // and a const reference to value_ref. + // act methods are feed with ref, value_ref and the parse result. + // + // (This doc uses convention available in actors.hpp) + // + // Constructor: + // ...(T& ref_, ValueT const& value_ref_); + // where ref_ and value_ref_ are stored in the holder. + // + // Action calls: + // act(ref, value_ref, value); + // act(ref, value_ref, first, last); + // + // () operators: both + // + /////////////////////////////////////////////////////////////////////////// + template< + typename T, + typename ValueT, + typename ActionT + > + class ref_const_ref_value_actor : public ActionT + { + private: + T& ref; + ValueT const& value_ref; + public: + ref_const_ref_value_actor( + T& ref_, + ValueT const& value_ref_ + ) + : + ref(ref_), + value_ref(value_ref_) + {} + + + template<typename T2> + void operator()(T2 const& val_) const + { + this->act(ref,value_ref,val_); // defined in ActionT + } + + + template<typename IteratorT> + void operator()( + IteratorT const& first_, + IteratorT const& last_ + ) const + { + this->act(ref,value_ref,first_,last_); // defined in ActionT + } + }; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} + +#endif diff --git a/boost/spirit/home/classic/actor/ref_value_actor.hpp b/boost/spirit/home/classic/actor/ref_value_actor.hpp new file mode 100644 index 0000000000..596e219b1e --- /dev/null +++ b/boost/spirit/home/classic/actor/ref_value_actor.hpp @@ -0,0 +1,82 @@ +/*============================================================================= + Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com) + Copyright (c) 2011 Bryce Lelbach + 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_ACTOR_REF_VALUE_ACTOR_HPP +#define BOOST_SPIRIT_ACTOR_REF_VALUE_ACTOR_HPP + +#include <boost/detail/workaround.hpp> + +#include <boost/spirit/home/classic/namespace.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(push) +#pragma warning(disable:4512) //assignment operator could not be generated +#endif + + /////////////////////////////////////////////////////////////////////////// + // Summary: + // A semantic action policy holder. This holder stores a reference to ref. + // act methods are feed with ref and the parse result. + // + // (This doc uses convention available in actors.hpp) + // + // Constructor: + // ...(T& ref_); + // where ref_ is stored. + // + // Action calls: + // act(ref, value); + // act(ref, first,last); + // + // () operators: both + // + /////////////////////////////////////////////////////////////////////////// + template< + typename T, + typename ActionT + > + class ref_value_actor : public ActionT + { + private: + T& ref; + public: + explicit + ref_value_actor(T& ref_) + : ref(ref_){} + + + template<typename T2> + void operator()(T2 const& val_) const + { + this->act(ref,val_); // defined in ActionT + } + + + template<typename IteratorT> + void operator()( + IteratorT const& first_, + IteratorT const& last_ + ) const + { + this->act(ref,first_,last_); // defined in ActionT + } + }; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(pop) +#endif + +}} + +#endif diff --git a/boost/spirit/home/classic/actor/swap_actor.hpp b/boost/spirit/home/classic/actor/swap_actor.hpp new file mode 100644 index 0000000000..f3fc5e4b1f --- /dev/null +++ b/boost/spirit/home/classic/actor/swap_actor.hpp @@ -0,0 +1,85 @@ +/*============================================================================= + Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com) + 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_ACTOR_SWAP_ACTOR_HPP +#define BOOST_SPIRIT_ACTOR_SWAP_ACTOR_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/actor/ref_value_actor.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // Summary: + // A semantic action policy that swaps values. + // (This doc uses convention available in actors.hpp) + // + // Actions (what it does): + // ref.swap( value_ref ); + // + // Policy name: + // swap_action + // + // Policy holder, corresponding helper method: + // ref_value_actor, swap_a( ref ); + // ref_const_ref_actor, swap_a( ref, value_ref ); + // + // () operators: both + // + // See also ref_value_actor and ref_const_ref_actor for more details. + /////////////////////////////////////////////////////////////////////////// + template< + typename T + > + class swap_actor + { + private: + T& ref; + T& swap_ref; + + public: + swap_actor( + T& ref_, + T& swap_ref_) + : ref(ref_), swap_ref(swap_ref_) + {}; + + template<typename T2> + void operator()(T2 const& /*val*/) const + { + ref.swap(swap_ref); + } + + + template<typename IteratorT> + void operator()( + IteratorT const& /*first*/, + IteratorT const& /*last*/ + ) const + { + ref.swap(swap_ref); + } + }; + + template< + typename T + > + inline swap_actor<T> swap_a( + T& ref_, + T& swap_ref_ + ) + { + return swap_actor<T>(ref_,swap_ref_); + } + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} + +#endif diff --git a/boost/spirit/home/classic/actor/typeof.hpp b/boost/spirit/home/classic/actor/typeof.hpp new file mode 100644 index 0000000000..9d4b91ce18 --- /dev/null +++ b/boost/spirit/home/classic/actor/typeof.hpp @@ -0,0 +1,74 @@ +/*============================================================================= + Copyright (c) 2006 Tobias Schwinger + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_ACTOR_TYPEOF_HPP) +#define BOOST_SPIRIT_ACTOR_TYPEOF_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/typeof/typeof.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + template<typename T, typename ActionT> class ref_actor; + + template<typename T, typename ActionT> class ref_value_actor; + + template<typename T, typename ValueT, typename ActionT> + + class ref_const_ref_actor; + template<typename T, typename ValueT, typename ActionT> + + class ref_const_ref_value_actor; + template<typename T, typename Value1T, typename Value2T, typename ActionT> + + class ref_const_ref_const_ref_actor; + + struct assign_action; + struct clear_action; + struct increment_action; + struct decrement_action; + struct push_back_action; + struct push_front_action; + struct insert_key_action; + struct insert_at_action; + struct assign_key_action; + + template<typename T> class swap_actor; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + + +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() + + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::ref_actor,2) +#if !defined(BOOST_SPIRIT_CORE_TYPEOF_HPP) +// this part also lives in the core master header and is deprecated there... +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::ref_value_actor,2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::ref_const_ref_actor,3) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::assign_action) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::push_back_action) +#endif +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::ref_const_ref_value_actor,3) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::ref_const_ref_const_ref_actor,4) + +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::clear_action) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::increment_action) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::decrement_action) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::push_front_action) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::insert_key_action) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::insert_at_action) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::assign_key_action) + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::swap_actor,1) + +#endif + diff --git a/boost/spirit/home/classic/attribute.hpp b/boost/spirit/home/classic/attribute.hpp new file mode 100644 index 0000000000..35b306b6a4 --- /dev/null +++ b/boost/spirit/home/classic/attribute.hpp @@ -0,0 +1,37 @@ +/*============================================================================= + Copyright (c) 2001-2003 Joel de Guzman + Copyright (c) 2002-2003 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_ATTRIBUTE_MAIN_HPP) +#define BOOST_SPIRIT_ATTRIBUTE_MAIN_HPP + +#include <boost/spirit/home/classic/version.hpp> + +/////////////////////////////////////////////////////////////////////////////// +// +// Master header for Spirit.Attributes +// +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// +// Phoenix predefined maximum limit. This limit defines the maximum +// number of elements a tuple can hold. This number defaults to 3. The +// actual maximum is rounded up in multiples of 3. Thus, if this value +// is 4, the actual limit is 6. The ultimate maximum limit in this +// implementation is 15. +// +/////////////////////////////////////////////////////////////////////////////// +#if !defined(PHOENIX_LIMIT) +#define PHOENIX_LIMIT 6 +#endif // !defined(PHOENIX_LIMIT) + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/spirit/home/classic/attribute/parametric.hpp> +#include <boost/spirit/home/classic/attribute/closure.hpp> + +#endif // !defined(BOOST_SPIRIT_ATTRIBUTE_MAIN_HPP) diff --git a/boost/spirit/home/classic/attribute/closure.hpp b/boost/spirit/home/classic/attribute/closure.hpp new file mode 100644 index 0000000000..681bc7fb04 --- /dev/null +++ b/boost/spirit/home/classic/attribute/closure.hpp @@ -0,0 +1,1083 @@ +/*============================================================================= + Copyright (c) 2001-2003 Joel de Guzman + Copyright (c) 2002-2003 Hartmut Kaiser + 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_CLOSURE_HPP +#define BOOST_SPIRIT_CLOSURE_HPP + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/core/composite/composite.hpp> +#include <boost/spirit/home/classic/core/non_terminal/parser_context.hpp> +#include <boost/spirit/home/classic/attribute/parametric.hpp> +#include <boost/spirit/home/classic/attribute/closure_context.hpp> +#include <boost/spirit/home/classic/attribute/closure_fwd.hpp> + +#include <boost/spirit/home/classic/phoenix/closures.hpp> +#include <boost/spirit/home/classic/phoenix/primitives.hpp> +#include <boost/spirit/home/classic/phoenix/casts.hpp> +#include <boost/spirit/home/classic/phoenix/operators.hpp> +#include <boost/spirit/home/classic/phoenix/tuple_helpers.hpp> + +#include <boost/static_assert.hpp> + +/////////////////////////////////////////////////////////////////////////////// +// +// Spirit predefined maximum closure limit. This limit defines the maximum +// number of elements a closure can hold. This number defaults to 3. The +// actual maximum is rounded up in multiples of 3. Thus, if this value +// is 4, the actual limit is 6. The ultimate maximum limit in this +// implementation is 15. +// +// It should NOT be greater than PHOENIX_LIMIT! +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(BOOST_SPIRIT_CLOSURE_LIMIT) +#define BOOST_SPIRIT_CLOSURE_LIMIT PHOENIX_LIMIT +#endif + +/////////////////////////////////////////////////////////////////////////////// +// +// ensure BOOST_SPIRIT_CLOSURE_LIMIT <= PHOENIX_LIMIT and SPIRIT_CLOSURE_LIMIT <= 15 +// +/////////////////////////////////////////////////////////////////////////////// +BOOST_STATIC_ASSERT(BOOST_SPIRIT_CLOSURE_LIMIT <= PHOENIX_LIMIT); +BOOST_STATIC_ASSERT(BOOST_SPIRIT_CLOSURE_LIMIT <= 15); + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // closure_context class + // + /////////////////////////////////////////////////////////////////////////// + template <typename ClosureT> + class closure_context : public parser_context_base + { + public: + + typedef typename ::phoenix::tuple_element<0, + typename ClosureT::tuple_t>::type attr_t; + typedef ClosureT base_t; + typedef closure_context_linker<closure_context<ClosureT> > + context_linker_t; + + closure_context(ClosureT const& clos) + : frame(clos) {} + + ~closure_context() {} + + template <typename ParserT, typename ScannerT> + void pre_parse(ParserT const&, ScannerT const&) {} + + template <typename ResultT, typename ParserT, typename ScannerT> + ResultT& post_parse(ResultT& hit, ParserT const&, ScannerT const&) + { hit.value(frame[::phoenix::tuple_index<0>()]); return hit; } + + private: + + ::phoenix::closure_frame<typename ClosureT::phoenix_closure_t> frame; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // init_closure_context class + // + // The init_closure_context class is a special parser context type + // which additionally initializes a closure contained in the derived + // parser with values from a given tuple. Please note, that this + // given tuple does not contain the required values directly, it + // contains phoenix::actor objects. These actors have to be + // dereferenced to gain the values to be used for initialization + // (this is done by the help of the phoenix::convert_actors<> + // template). + // + /////////////////////////////////////////////////////////////////////////// + + template <typename ClosureT> + class init_closure_context : public parser_context_base + { + typedef typename ClosureT::tuple_t tuple_t; + typedef typename ClosureT::closure_t closure_t; + + public: + + init_closure_context(ClosureT const& clos) + : frame(clos.subject(), ::phoenix::convert_actors<tuple_t>(clos.init)) {} + + ~init_closure_context() {} + + template <typename ParserT, typename ScannerT> + void pre_parse(ParserT const& /*p*/, ScannerT const&) {} + + template <typename ResultT, typename ParserT, typename ScannerT> + ResultT& post_parse(ResultT& hit, ParserT const&, ScannerT const&) + { hit.value(frame[::phoenix::tuple_index<0>()]); return hit; } + + private: + + ::phoenix::closure_frame<closure_t> frame; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // init_closure_parser class + // + /////////////////////////////////////////////////////////////////////////// + template <typename ParserT, typename ActorTupleT> + struct init_closure_parser + : public unary<ParserT, parser<init_closure_parser<ParserT, ActorTupleT> > > + { + typedef init_closure_parser<ParserT, ActorTupleT> self_t; + typedef unary<ParserT, parser<self_t> > base_t; + typedef typename ParserT::phoenix_closure_t closure_t; + typedef typename ParserT::tuple_t tuple_t; + typedef typename ::phoenix::tuple_element<0, tuple_t>::type attr_t; + + template <typename ScannerT> + struct result + { + typedef typename match_result<ScannerT, attr_t>::type type; + }; + + init_closure_parser(ParserT const& p, ActorTupleT const& init_) + : base_t(p), init(init_) {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse_main(ScannerT const& scan) const + { + return this->subject().parse_main(scan); + } + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef init_closure_context<self_t> init_context_t; + typedef parser_scanner_linker<ScannerT> scanner_t; + typedef closure_context_linker<init_context_t> context_t; + typedef typename parser_result<self_t, ScannerT>::type result_t; + BOOST_SPIRIT_CONTEXT_PARSE( + scan, *this, scanner_t, context_t, result_t); + } + + ActorTupleT init; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // closure class + // + /////////////////////////////////////////////////////////////////////////// + template < + typename DerivedT + , typename T0 + , typename T1 + , typename T2 + + #if BOOST_SPIRIT_CLOSURE_LIMIT > 3 + , typename T3 + , typename T4 + , typename T5 + + #if BOOST_SPIRIT_CLOSURE_LIMIT > 6 + , typename T6 + , typename T7 + , typename T8 + + #if BOOST_SPIRIT_CLOSURE_LIMIT > 9 + , typename T9 + , typename T10 + , typename T11 + + #if BOOST_SPIRIT_CLOSURE_LIMIT > 12 + , typename T12 + , typename T13 + , typename T14 + #endif + #endif + #endif + #endif + > + struct closure : + public ::phoenix::closure< + T0, T1, T2 + #if BOOST_SPIRIT_CLOSURE_LIMIT > 3 + , T3, T4, T5 + #if BOOST_SPIRIT_CLOSURE_LIMIT > 6 + , T6, T7, T8 + #if BOOST_SPIRIT_CLOSURE_LIMIT > 9 + , T9, T10, T11 + #if BOOST_SPIRIT_CLOSURE_LIMIT > 12 + , T12, T13, T14 + #endif + #endif + #endif + #endif + > + { + typedef ::phoenix::closure< + T0, T1, T2 + #if BOOST_SPIRIT_CLOSURE_LIMIT > 3 + , T3, T4, T5 + #if BOOST_SPIRIT_CLOSURE_LIMIT > 6 + , T6, T7, T8 + #if BOOST_SPIRIT_CLOSURE_LIMIT > 9 + , T9, T10, T11 + #if BOOST_SPIRIT_CLOSURE_LIMIT > 12 + , T12, T13, T14 + #endif + #endif + #endif + #endif + > phoenix_closure_t; + + typedef closure_context<DerivedT> context_t; + + template <typename DerivedT2> + struct aux + { + DerivedT2& aux_derived() + { return *static_cast<DerivedT2*>(this); } + + DerivedT2 const& aux_derived() const + { return *static_cast<DerivedT2 const*>(this); } + + // initialization functions + template <typename A> + init_closure_parser< + DerivedT2, + ::phoenix::tuple< + typename ::phoenix::as_actor<A>::type + > + > + operator()(A const &a) const + { + typedef typename ::phoenix::as_actor<A>::type a_t; + typedef ::phoenix::tuple<a_t> actor_tuple_t; + + return init_closure_parser<DerivedT2, actor_tuple_t>( + aux_derived(), + actor_tuple_t( + ::phoenix::as_actor<A>::convert(a) + ) + ); + } + + template <typename A, typename B> + init_closure_parser< + DerivedT2, + ::phoenix::tuple< + typename ::phoenix::as_actor<A>::type, + typename ::phoenix::as_actor<B>::type + > + > + operator()(A const &a, B const &b) const + { + typedef typename ::phoenix::as_actor<A>::type a_t; + typedef typename ::phoenix::as_actor<B>::type b_t; + typedef ::phoenix::tuple<a_t, b_t> actor_tuple_t; + + return init_closure_parser<DerivedT2, actor_tuple_t>( + aux_derived(), + actor_tuple_t( + ::phoenix::as_actor<A>::convert(a), + ::phoenix::as_actor<B>::convert(b) + ) + ); + } + + template <typename A, typename B, typename C> + init_closure_parser< + DerivedT2, + ::phoenix::tuple< + typename ::phoenix::as_actor<A>::type, + typename ::phoenix::as_actor<B>::type, + typename ::phoenix::as_actor<C>::type + > + > + operator()(A const &a, B const &b, C const &c) const + { + typedef typename ::phoenix::as_actor<A>::type a_t; + typedef typename ::phoenix::as_actor<B>::type b_t; + typedef typename ::phoenix::as_actor<C>::type c_t; + typedef ::phoenix::tuple<a_t, b_t, c_t> actor_tuple_t; + + return init_closure_parser<DerivedT2, actor_tuple_t>( + aux_derived(), + actor_tuple_t( + ::phoenix::as_actor<A>::convert(a), + ::phoenix::as_actor<B>::convert(b), + ::phoenix::as_actor<C>::convert(c) + ) + ); + } + + #if BOOST_SPIRIT_CLOSURE_LIMIT > 3 + + template < + typename A, typename B, typename C, typename D + > + init_closure_parser< + DerivedT2, + ::phoenix::tuple< + typename ::phoenix::as_actor<A>::type, + typename ::phoenix::as_actor<B>::type, + typename ::phoenix::as_actor<C>::type, + typename ::phoenix::as_actor<D>::type + > + > + operator()( + A const &a, B const &b, C const &c, D const &d + ) const + { + typedef typename ::phoenix::as_actor<A>::type a_t; + typedef typename ::phoenix::as_actor<B>::type b_t; + typedef typename ::phoenix::as_actor<C>::type c_t; + typedef typename ::phoenix::as_actor<D>::type d_t; + typedef ::phoenix::tuple< + a_t, b_t, c_t, d_t + > actor_tuple_t; + + return init_closure_parser<DerivedT2, actor_tuple_t>( + aux_derived(), + actor_tuple_t( + ::phoenix::as_actor<A>::convert(a), + ::phoenix::as_actor<B>::convert(b), + ::phoenix::as_actor<C>::convert(c), + ::phoenix::as_actor<D>::convert(d) + ) + ); + } + + template < + typename A, typename B, typename C, typename D, typename E + > + init_closure_parser< + DerivedT2, + ::phoenix::tuple< + typename ::phoenix::as_actor<A>::type, + typename ::phoenix::as_actor<B>::type, + typename ::phoenix::as_actor<C>::type, + typename ::phoenix::as_actor<D>::type, + typename ::phoenix::as_actor<E>::type + > + > + operator()( + A const &a, B const &b, C const &c, D const &d, E const &e + ) const + { + typedef typename ::phoenix::as_actor<A>::type a_t; + typedef typename ::phoenix::as_actor<B>::type b_t; + typedef typename ::phoenix::as_actor<C>::type c_t; + typedef typename ::phoenix::as_actor<D>::type d_t; + typedef typename ::phoenix::as_actor<E>::type e_t; + typedef ::phoenix::tuple< + a_t, b_t, c_t, d_t, e_t + > actor_tuple_t; + + return init_closure_parser<DerivedT2, actor_tuple_t>( + aux_derived(), + actor_tuple_t( + ::phoenix::as_actor<A>::convert(a), + ::phoenix::as_actor<B>::convert(b), + ::phoenix::as_actor<C>::convert(c), + ::phoenix::as_actor<D>::convert(d), + ::phoenix::as_actor<E>::convert(e) + ) + ); + } + + template < + typename A, typename B, typename C, typename D, typename E, + typename F + > + init_closure_parser< + DerivedT2, + ::phoenix::tuple< + typename ::phoenix::as_actor<A>::type, + typename ::phoenix::as_actor<B>::type, + typename ::phoenix::as_actor<C>::type, + typename ::phoenix::as_actor<D>::type, + typename ::phoenix::as_actor<E>::type, + typename ::phoenix::as_actor<F>::type + > + > + operator()( + A const &a, B const &b, C const &c, D const &d, E const &e, + F const &f + ) const + { + typedef typename ::phoenix::as_actor<A>::type a_t; + typedef typename ::phoenix::as_actor<B>::type b_t; + typedef typename ::phoenix::as_actor<C>::type c_t; + typedef typename ::phoenix::as_actor<D>::type d_t; + typedef typename ::phoenix::as_actor<E>::type e_t; + typedef typename ::phoenix::as_actor<F>::type f_t; + typedef ::phoenix::tuple< + a_t, b_t, c_t, d_t, e_t, f_t + > actor_tuple_t; + + return init_closure_parser<DerivedT2, actor_tuple_t>( + aux_derived(), + actor_tuple_t( + ::phoenix::as_actor<A>::convert(a), + ::phoenix::as_actor<B>::convert(b), + ::phoenix::as_actor<C>::convert(c), + ::phoenix::as_actor<D>::convert(d), + ::phoenix::as_actor<E>::convert(e), + ::phoenix::as_actor<F>::convert(f) + ) + ); + } + + #if BOOST_SPIRIT_CLOSURE_LIMIT > 6 + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G + > + init_closure_parser< + DerivedT2, + ::phoenix::tuple< + typename ::phoenix::as_actor<A>::type, + typename ::phoenix::as_actor<B>::type, + typename ::phoenix::as_actor<C>::type, + typename ::phoenix::as_actor<D>::type, + typename ::phoenix::as_actor<E>::type, + typename ::phoenix::as_actor<F>::type, + typename ::phoenix::as_actor<G>::type + > + > + operator()( + A const &a, B const &b, C const &c, D const &d, E const &e, + F const &f, G const &g + ) const + { + typedef typename ::phoenix::as_actor<A>::type a_t; + typedef typename ::phoenix::as_actor<B>::type b_t; + typedef typename ::phoenix::as_actor<C>::type c_t; + typedef typename ::phoenix::as_actor<D>::type d_t; + typedef typename ::phoenix::as_actor<E>::type e_t; + typedef typename ::phoenix::as_actor<F>::type f_t; + typedef typename ::phoenix::as_actor<G>::type g_t; + typedef ::phoenix::tuple< + a_t, b_t, c_t, d_t, e_t, f_t, g_t + > actor_tuple_t; + + return init_closure_parser<DerivedT2, actor_tuple_t>( + aux_derived(), + actor_tuple_t( + ::phoenix::as_actor<A>::convert(a), + ::phoenix::as_actor<B>::convert(b), + ::phoenix::as_actor<C>::convert(c), + ::phoenix::as_actor<D>::convert(d), + ::phoenix::as_actor<E>::convert(e), + ::phoenix::as_actor<F>::convert(f), + ::phoenix::as_actor<G>::convert(g) + ) + ); + } + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H + > + init_closure_parser< + DerivedT2, + ::phoenix::tuple< + typename ::phoenix::as_actor<A>::type, + typename ::phoenix::as_actor<B>::type, + typename ::phoenix::as_actor<C>::type, + typename ::phoenix::as_actor<D>::type, + typename ::phoenix::as_actor<E>::type, + typename ::phoenix::as_actor<F>::type, + typename ::phoenix::as_actor<G>::type, + typename ::phoenix::as_actor<H>::type + > + > + operator()( + A const &a, B const &b, C const &c, D const &d, E const &e, + F const &f, G const &g, H const &h + ) const + { + typedef typename ::phoenix::as_actor<A>::type a_t; + typedef typename ::phoenix::as_actor<B>::type b_t; + typedef typename ::phoenix::as_actor<C>::type c_t; + typedef typename ::phoenix::as_actor<D>::type d_t; + typedef typename ::phoenix::as_actor<E>::type e_t; + typedef typename ::phoenix::as_actor<F>::type f_t; + typedef typename ::phoenix::as_actor<G>::type g_t; + typedef typename ::phoenix::as_actor<H>::type h_t; + typedef ::phoenix::tuple< + a_t, b_t, c_t, d_t, e_t, f_t, g_t, h_t + > actor_tuple_t; + + return init_closure_parser<DerivedT2, actor_tuple_t>( + aux_derived(), + actor_tuple_t( + ::phoenix::as_actor<A>::convert(a), + ::phoenix::as_actor<B>::convert(b), + ::phoenix::as_actor<C>::convert(c), + ::phoenix::as_actor<D>::convert(d), + ::phoenix::as_actor<E>::convert(e), + ::phoenix::as_actor<F>::convert(f), + ::phoenix::as_actor<G>::convert(g), + ::phoenix::as_actor<H>::convert(h) + ) + ); + } + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I + > + init_closure_parser< + DerivedT2, + ::phoenix::tuple< + typename ::phoenix::as_actor<A>::type, + typename ::phoenix::as_actor<B>::type, + typename ::phoenix::as_actor<C>::type, + typename ::phoenix::as_actor<D>::type, + typename ::phoenix::as_actor<E>::type, + typename ::phoenix::as_actor<F>::type, + typename ::phoenix::as_actor<G>::type, + typename ::phoenix::as_actor<H>::type, + typename ::phoenix::as_actor<I>::type + > + > + operator()( + A const &a, B const &b, C const &c, D const &d, E const &e, + F const &f, G const &g, H const &h, I const &i + ) const + { + typedef typename ::phoenix::as_actor<A>::type a_t; + typedef typename ::phoenix::as_actor<B>::type b_t; + typedef typename ::phoenix::as_actor<C>::type c_t; + typedef typename ::phoenix::as_actor<D>::type d_t; + typedef typename ::phoenix::as_actor<E>::type e_t; + typedef typename ::phoenix::as_actor<F>::type f_t; + typedef typename ::phoenix::as_actor<G>::type g_t; + typedef typename ::phoenix::as_actor<H>::type h_t; + typedef typename ::phoenix::as_actor<I>::type i_t; + typedef ::phoenix::tuple< + a_t, b_t, c_t, d_t, e_t, f_t, g_t, h_t, i_t + > actor_tuple_t; + + return init_closure_parser<DerivedT2, actor_tuple_t>( + aux_derived(), + actor_tuple_t( + ::phoenix::as_actor<A>::convert(a), + ::phoenix::as_actor<B>::convert(b), + ::phoenix::as_actor<C>::convert(c), + ::phoenix::as_actor<D>::convert(d), + ::phoenix::as_actor<E>::convert(e), + ::phoenix::as_actor<F>::convert(f), + ::phoenix::as_actor<G>::convert(g), + ::phoenix::as_actor<H>::convert(h), + ::phoenix::as_actor<I>::convert(i) + ) + ); + } + + #if BOOST_SPIRIT_CLOSURE_LIMIT > 9 + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J + > + init_closure_parser< + DerivedT2, + ::phoenix::tuple< + typename ::phoenix::as_actor<A>::type, + typename ::phoenix::as_actor<B>::type, + typename ::phoenix::as_actor<C>::type, + typename ::phoenix::as_actor<D>::type, + typename ::phoenix::as_actor<E>::type, + typename ::phoenix::as_actor<F>::type, + typename ::phoenix::as_actor<G>::type, + typename ::phoenix::as_actor<H>::type, + typename ::phoenix::as_actor<I>::type, + typename ::phoenix::as_actor<J>::type + > + > + operator()( + A const &a, B const &b, C const &c, D const &d, E const &e, + F const &f, G const &g, H const &h, I const &i, J const &j + ) const + { + typedef typename ::phoenix::as_actor<A>::type a_t; + typedef typename ::phoenix::as_actor<B>::type b_t; + typedef typename ::phoenix::as_actor<C>::type c_t; + typedef typename ::phoenix::as_actor<D>::type d_t; + typedef typename ::phoenix::as_actor<E>::type e_t; + typedef typename ::phoenix::as_actor<F>::type f_t; + typedef typename ::phoenix::as_actor<G>::type g_t; + typedef typename ::phoenix::as_actor<H>::type h_t; + typedef typename ::phoenix::as_actor<I>::type i_t; + typedef typename ::phoenix::as_actor<J>::type j_t; + typedef ::phoenix::tuple< + a_t, b_t, c_t, d_t, e_t, f_t, g_t, h_t, i_t, j_t + > actor_tuple_t; + + return init_closure_parser<DerivedT2, actor_tuple_t>( + aux_derived(), + actor_tuple_t( + ::phoenix::as_actor<A>::convert(a), + ::phoenix::as_actor<B>::convert(b), + ::phoenix::as_actor<C>::convert(c), + ::phoenix::as_actor<D>::convert(d), + ::phoenix::as_actor<E>::convert(e), + ::phoenix::as_actor<F>::convert(f), + ::phoenix::as_actor<G>::convert(g), + ::phoenix::as_actor<H>::convert(h), + ::phoenix::as_actor<I>::convert(i), + ::phoenix::as_actor<J>::convert(j) + ) + ); + } + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K + > + init_closure_parser< + DerivedT2, + ::phoenix::tuple< + typename ::phoenix::as_actor<A>::type, + typename ::phoenix::as_actor<B>::type, + typename ::phoenix::as_actor<C>::type, + typename ::phoenix::as_actor<D>::type, + typename ::phoenix::as_actor<E>::type, + typename ::phoenix::as_actor<F>::type, + typename ::phoenix::as_actor<G>::type, + typename ::phoenix::as_actor<H>::type, + typename ::phoenix::as_actor<I>::type, + typename ::phoenix::as_actor<J>::type, + typename ::phoenix::as_actor<K>::type + > + > + operator()( + A const &a, B const &b, C const &c, D const &d, E const &e, + F const &f, G const &g, H const &h, I const &i, J const &j, + K const &k + ) const + { + typedef typename ::phoenix::as_actor<A>::type a_t; + typedef typename ::phoenix::as_actor<B>::type b_t; + typedef typename ::phoenix::as_actor<C>::type c_t; + typedef typename ::phoenix::as_actor<D>::type d_t; + typedef typename ::phoenix::as_actor<E>::type e_t; + typedef typename ::phoenix::as_actor<F>::type f_t; + typedef typename ::phoenix::as_actor<G>::type g_t; + typedef typename ::phoenix::as_actor<H>::type h_t; + typedef typename ::phoenix::as_actor<I>::type i_t; + typedef typename ::phoenix::as_actor<J>::type j_t; + typedef typename ::phoenix::as_actor<K>::type k_t; + typedef ::phoenix::tuple< + a_t, b_t, c_t, d_t, e_t, f_t, g_t, h_t, i_t, j_t, + k_t + > actor_tuple_t; + + return init_closure_parser<DerivedT2, actor_tuple_t>( + aux_derived(), + actor_tuple_t( + ::phoenix::as_actor<A>::convert(a), + ::phoenix::as_actor<B>::convert(b), + ::phoenix::as_actor<C>::convert(c), + ::phoenix::as_actor<D>::convert(d), + ::phoenix::as_actor<E>::convert(e), + ::phoenix::as_actor<F>::convert(f), + ::phoenix::as_actor<G>::convert(g), + ::phoenix::as_actor<H>::convert(h), + ::phoenix::as_actor<I>::convert(i), + ::phoenix::as_actor<J>::convert(j), + ::phoenix::as_actor<K>::convert(k) + ) + ); + } + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L + > + init_closure_parser< + DerivedT2, + ::phoenix::tuple< + typename ::phoenix::as_actor<A>::type, + typename ::phoenix::as_actor<B>::type, + typename ::phoenix::as_actor<C>::type, + typename ::phoenix::as_actor<D>::type, + typename ::phoenix::as_actor<E>::type, + typename ::phoenix::as_actor<F>::type, + typename ::phoenix::as_actor<G>::type, + typename ::phoenix::as_actor<H>::type, + typename ::phoenix::as_actor<I>::type, + typename ::phoenix::as_actor<J>::type, + typename ::phoenix::as_actor<K>::type, + typename ::phoenix::as_actor<L>::type + > + > + operator()( + A const &a, B const &b, C const &c, D const &d, E const &e, + F const &f, G const &g, H const &h, I const &i, J const &j, + K const &k, L const &l + ) const + { + typedef typename ::phoenix::as_actor<A>::type a_t; + typedef typename ::phoenix::as_actor<B>::type b_t; + typedef typename ::phoenix::as_actor<C>::type c_t; + typedef typename ::phoenix::as_actor<D>::type d_t; + typedef typename ::phoenix::as_actor<E>::type e_t; + typedef typename ::phoenix::as_actor<F>::type f_t; + typedef typename ::phoenix::as_actor<G>::type g_t; + typedef typename ::phoenix::as_actor<H>::type h_t; + typedef typename ::phoenix::as_actor<I>::type i_t; + typedef typename ::phoenix::as_actor<J>::type j_t; + typedef typename ::phoenix::as_actor<K>::type k_t; + typedef typename ::phoenix::as_actor<L>::type l_t; + typedef ::phoenix::tuple< + a_t, b_t, c_t, d_t, e_t, f_t, g_t, h_t, i_t, j_t, + k_t, l_t + > actor_tuple_t; + + return init_closure_parser<DerivedT2, actor_tuple_t>( + aux_derived(), + actor_tuple_t( + ::phoenix::as_actor<A>::convert(a), + ::phoenix::as_actor<B>::convert(b), + ::phoenix::as_actor<C>::convert(c), + ::phoenix::as_actor<D>::convert(d), + ::phoenix::as_actor<E>::convert(e), + ::phoenix::as_actor<F>::convert(f), + ::phoenix::as_actor<G>::convert(g), + ::phoenix::as_actor<H>::convert(h), + ::phoenix::as_actor<I>::convert(i), + ::phoenix::as_actor<J>::convert(j), + ::phoenix::as_actor<K>::convert(k), + ::phoenix::as_actor<L>::convert(l) + ) + ); + } + + #if BOOST_SPIRIT_CLOSURE_LIMIT > 12 + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M + > + init_closure_parser< + DerivedT2, + ::phoenix::tuple< + typename ::phoenix::as_actor<A>::type, + typename ::phoenix::as_actor<B>::type, + typename ::phoenix::as_actor<C>::type, + typename ::phoenix::as_actor<D>::type, + typename ::phoenix::as_actor<E>::type, + typename ::phoenix::as_actor<F>::type, + typename ::phoenix::as_actor<G>::type, + typename ::phoenix::as_actor<H>::type, + typename ::phoenix::as_actor<I>::type, + typename ::phoenix::as_actor<J>::type, + typename ::phoenix::as_actor<K>::type, + typename ::phoenix::as_actor<L>::type, + typename ::phoenix::as_actor<M>::type + > + > + operator()( + A const &a, B const &b, C const &c, D const &d, E const &e, + F const &f, G const &g, H const &h, I const &i, J const &j, + K const &k, L const &l, M const &m + ) const + { + typedef typename ::phoenix::as_actor<A>::type a_t; + typedef typename ::phoenix::as_actor<B>::type b_t; + typedef typename ::phoenix::as_actor<C>::type c_t; + typedef typename ::phoenix::as_actor<D>::type d_t; + typedef typename ::phoenix::as_actor<E>::type e_t; + typedef typename ::phoenix::as_actor<F>::type f_t; + typedef typename ::phoenix::as_actor<G>::type g_t; + typedef typename ::phoenix::as_actor<H>::type h_t; + typedef typename ::phoenix::as_actor<I>::type i_t; + typedef typename ::phoenix::as_actor<J>::type j_t; + typedef typename ::phoenix::as_actor<K>::type k_t; + typedef typename ::phoenix::as_actor<L>::type l_t; + typedef typename ::phoenix::as_actor<M>::type m_t; + typedef ::phoenix::tuple< + a_t, b_t, c_t, d_t, e_t, f_t, g_t, h_t, i_t, j_t, + k_t, l_t, m_t + > actor_tuple_t; + + return init_closure_parser<DerivedT2, actor_tuple_t>( + aux_derived(), + actor_tuple_t( + ::phoenix::as_actor<A>::convert(a), + ::phoenix::as_actor<B>::convert(b), + ::phoenix::as_actor<C>::convert(c), + ::phoenix::as_actor<D>::convert(d), + ::phoenix::as_actor<E>::convert(e), + ::phoenix::as_actor<F>::convert(f), + ::phoenix::as_actor<G>::convert(g), + ::phoenix::as_actor<H>::convert(h), + ::phoenix::as_actor<I>::convert(i), + ::phoenix::as_actor<J>::convert(j), + ::phoenix::as_actor<K>::convert(k), + ::phoenix::as_actor<L>::convert(l), + ::phoenix::as_actor<M>::convert(m) + ) + ); + } + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M, typename N + > + init_closure_parser< + DerivedT2, + ::phoenix::tuple< + typename ::phoenix::as_actor<A>::type, + typename ::phoenix::as_actor<B>::type, + typename ::phoenix::as_actor<C>::type, + typename ::phoenix::as_actor<D>::type, + typename ::phoenix::as_actor<E>::type, + typename ::phoenix::as_actor<F>::type, + typename ::phoenix::as_actor<G>::type, + typename ::phoenix::as_actor<H>::type, + typename ::phoenix::as_actor<I>::type, + typename ::phoenix::as_actor<J>::type, + typename ::phoenix::as_actor<K>::type, + typename ::phoenix::as_actor<L>::type, + typename ::phoenix::as_actor<M>::type, + typename ::phoenix::as_actor<N>::type + > + > + operator()( + A const &a, B const &b, C const &c, D const &d, E const &e, + F const &f, G const &g, H const &h, I const &i, J const &j, + K const &k, L const &l, M const &m, N const &n + ) const + { + typedef typename ::phoenix::as_actor<A>::type a_t; + typedef typename ::phoenix::as_actor<B>::type b_t; + typedef typename ::phoenix::as_actor<C>::type c_t; + typedef typename ::phoenix::as_actor<D>::type d_t; + typedef typename ::phoenix::as_actor<E>::type e_t; + typedef typename ::phoenix::as_actor<F>::type f_t; + typedef typename ::phoenix::as_actor<G>::type g_t; + typedef typename ::phoenix::as_actor<H>::type h_t; + typedef typename ::phoenix::as_actor<I>::type i_t; + typedef typename ::phoenix::as_actor<J>::type j_t; + typedef typename ::phoenix::as_actor<K>::type k_t; + typedef typename ::phoenix::as_actor<L>::type l_t; + typedef typename ::phoenix::as_actor<M>::type m_t; + typedef typename ::phoenix::as_actor<N>::type n_t; + typedef ::phoenix::tuple< + a_t, b_t, c_t, d_t, e_t, f_t, g_t, h_t, i_t, j_t, + k_t, l_t, m_t, n_t + > actor_tuple_t; + + return init_closure_parser<DerivedT2, actor_tuple_t>( + aux_derived(), + actor_tuple_t( + ::phoenix::as_actor<A>::convert(a), + ::phoenix::as_actor<B>::convert(b), + ::phoenix::as_actor<C>::convert(c), + ::phoenix::as_actor<D>::convert(d), + ::phoenix::as_actor<E>::convert(e), + ::phoenix::as_actor<F>::convert(f), + ::phoenix::as_actor<G>::convert(g), + ::phoenix::as_actor<H>::convert(h), + ::phoenix::as_actor<I>::convert(i), + ::phoenix::as_actor<J>::convert(j), + ::phoenix::as_actor<K>::convert(k), + ::phoenix::as_actor<L>::convert(l), + ::phoenix::as_actor<M>::convert(m), + ::phoenix::as_actor<N>::convert(n) + ) + ); + } + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M, typename N, typename O + > + init_closure_parser< + DerivedT2, + ::phoenix::tuple< + typename ::phoenix::as_actor<A>::type, + typename ::phoenix::as_actor<B>::type, + typename ::phoenix::as_actor<C>::type, + typename ::phoenix::as_actor<D>::type, + typename ::phoenix::as_actor<E>::type, + typename ::phoenix::as_actor<F>::type, + typename ::phoenix::as_actor<G>::type, + typename ::phoenix::as_actor<H>::type, + typename ::phoenix::as_actor<I>::type, + typename ::phoenix::as_actor<J>::type, + typename ::phoenix::as_actor<K>::type, + typename ::phoenix::as_actor<L>::type, + typename ::phoenix::as_actor<M>::type, + typename ::phoenix::as_actor<N>::type, + typename ::phoenix::as_actor<O>::type + > + > + operator()( + A const &a, B const &b, C const &c, D const &d, E const &e, + F const &f, G const &g, H const &h, I const &i, J const &j, + K const &k, L const &l, M const &m, N const &n, O const &o + ) const + { + typedef typename ::phoenix::as_actor<A>::type a_t; + typedef typename ::phoenix::as_actor<B>::type b_t; + typedef typename ::phoenix::as_actor<C>::type c_t; + typedef typename ::phoenix::as_actor<D>::type d_t; + typedef typename ::phoenix::as_actor<E>::type e_t; + typedef typename ::phoenix::as_actor<F>::type f_t; + typedef typename ::phoenix::as_actor<G>::type g_t; + typedef typename ::phoenix::as_actor<H>::type h_t; + typedef typename ::phoenix::as_actor<I>::type i_t; + typedef typename ::phoenix::as_actor<J>::type j_t; + typedef typename ::phoenix::as_actor<K>::type k_t; + typedef typename ::phoenix::as_actor<L>::type l_t; + typedef typename ::phoenix::as_actor<M>::type m_t; + typedef typename ::phoenix::as_actor<N>::type n_t; + typedef typename ::phoenix::as_actor<O>::type o_t; + typedef ::phoenix::tuple< + a_t, b_t, c_t, d_t, e_t, f_t, g_t, h_t, i_t, j_t, + k_t, l_t, m_t, n_t, o_t + > actor_tuple_t; + + return init_closure_parser<DerivedT2, actor_tuple_t>( + aux_derived(), + actor_tuple_t( + ::phoenix::as_actor<A>::convert(a), + ::phoenix::as_actor<B>::convert(b), + ::phoenix::as_actor<C>::convert(c), + ::phoenix::as_actor<D>::convert(d), + ::phoenix::as_actor<E>::convert(e), + ::phoenix::as_actor<F>::convert(f), + ::phoenix::as_actor<G>::convert(g), + ::phoenix::as_actor<H>::convert(h), + ::phoenix::as_actor<I>::convert(i), + ::phoenix::as_actor<J>::convert(j), + ::phoenix::as_actor<K>::convert(k), + ::phoenix::as_actor<L>::convert(l), + ::phoenix::as_actor<M>::convert(m), + ::phoenix::as_actor<N>::convert(n), + ::phoenix::as_actor<O>::convert(o) + ) + ); + } + + #endif + #endif + #endif + #endif + }; + + ~closure() {} + }; + + /////////////////////////////////////////////////////////////////////////// + // + // overloads for chseq_p and str_p taking in phoenix actors + // + /////////////////////////////////////////////////////////////////////////// + template <typename ActorT> + struct container_begin + { + typedef container_begin<ActorT> self_t; + + template <typename TupleT> + struct result + { + typedef typename ::phoenix::actor_result<ActorT, TupleT> + ::plain_type::iterator type; + }; + + container_begin(ActorT actor_) + : actor(actor_) {} + + template <typename TupleT> + typename ::phoenix::actor_result<self_t, TupleT>::type + eval(TupleT const& /*args*/) const + { return actor().begin(); } + + ActorT actor; + }; + + template <typename ActorT> + struct container_end + { + typedef container_begin<ActorT> self_t; + + template <typename TupleT> + struct result + { + typedef typename ::phoenix::actor_result<ActorT, TupleT> + ::plain_type::iterator type; + }; + + container_end(ActorT actor_) + : actor(actor_) {} + + template <typename TupleT> + typename ::phoenix::actor_result<self_t, TupleT>::type + eval(TupleT const& /*args*/) const + { return actor().end(); } + + ActorT actor; + }; + + template <typename BaseT> + inline f_chseq< + ::phoenix::actor<container_begin< ::phoenix::actor<BaseT> > >, + ::phoenix::actor<container_end< ::phoenix::actor<BaseT> > > + > + f_chseq_p(::phoenix::actor<BaseT> const& a) + { + typedef ::phoenix::actor<container_begin< ::phoenix::actor<BaseT> > > + container_begin_t; + typedef ::phoenix::actor<container_end< ::phoenix::actor<BaseT> > > + container_end_t; + typedef f_chseq<container_begin_t, container_end_t> result_t; + + return result_t(container_begin_t(a), container_end_t(a)); + } + + template <typename BaseT> + inline f_strlit< + ::phoenix::actor<container_begin< ::phoenix::actor<BaseT> > >, + ::phoenix::actor<container_end< ::phoenix::actor<BaseT> > > + > + f_str_p(::phoenix::actor<BaseT> const& a) + { + typedef ::phoenix::actor<container_begin< ::phoenix::actor<BaseT> > > + container_begin_t; + typedef ::phoenix::actor<container_end< ::phoenix::actor<BaseT> > > + container_end_t; + typedef f_strlit<container_begin_t, container_end_t> result_t; + + return result_t(container_begin_t(a), container_end_t(a)); + } + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif diff --git a/boost/spirit/home/classic/attribute/closure_context.hpp b/boost/spirit/home/classic/attribute/closure_context.hpp new file mode 100644 index 0000000000..e366854964 --- /dev/null +++ b/boost/spirit/home/classic/attribute/closure_context.hpp @@ -0,0 +1,56 @@ +/*============================================================================= + Copyright (c) 2002-2003 Joel de Guzman + Copyright (c) 2002-2003 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_CLOSURE_CONTEXT_HPP) +#define BOOST_SPIRIT_CLOSURE_CONTEXT_HPP + +#include <boost/spirit/home/classic/namespace.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +#if !defined(BOOST_SPIRIT_CLOSURE_CONTEXT_LINKER_DEFINED) +#define BOOST_SPIRIT_CLOSURE_CONTEXT_LINKER_DEFINED + +/////////////////////////////////////////////////////////////////////////////// +// +// closure_context_linker +// { helper template for the closure extendability } +// +// This classes can be 'overloaded' (defined elsewhere), to plug +// in additional functionality into the closure parsing process. +// +/////////////////////////////////////////////////////////////////////////////// + +template<typename ContextT> +struct closure_context_linker : public ContextT +{ + template <typename ParserT> + closure_context_linker(ParserT const& p) + : ContextT(p) {} + + template <typename ParserT, typename ScannerT> + void pre_parse(ParserT const& p, ScannerT const& scan) + { ContextT::pre_parse(p, scan); } + + template <typename ResultT, typename ParserT, typename ScannerT> + ResultT& + post_parse(ResultT& hit, ParserT const& p, ScannerT const& scan) + { return ContextT::post_parse(hit, p, scan); } +}; + +#endif // !defined(BOOST_SPIRIT_CLOSURE_CONTEXT_LINKER_DEFINED) + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif // BOOST_SPIRIT_CLOSURE_CONTEXT_HPP diff --git a/boost/spirit/home/classic/attribute/closure_fwd.hpp b/boost/spirit/home/classic/attribute/closure_fwd.hpp new file mode 100644 index 0000000000..033d619c2f --- /dev/null +++ b/boost/spirit/home/classic/attribute/closure_fwd.hpp @@ -0,0 +1,69 @@ +/*============================================================================= + Copyright (c) 2006 Tobias Schwinger + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_CLOSURE_FWD_HPP) +#define BOOST_SPIRIT_CLOSURE_FWD_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/phoenix/tuples.hpp> + +#if !defined(BOOST_SPIRIT_CLOSURE_LIMIT) +# define BOOST_SPIRIT_CLOSURE_LIMIT PHOENIX_LIMIT +#endif + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + template<typename ClosureT> + class closure_context; + + template <typename ClosureT> + class init_closure_context; + + template <typename ParserT, typename ActorTupleT> + struct init_closure_parser; + + template < + typename DerivedT + , typename T0 = ::phoenix::nil_t + , typename T1 = ::phoenix::nil_t + , typename T2 = ::phoenix::nil_t + + #if BOOST_SPIRIT_CLOSURE_LIMIT > 3 + , typename T3 = ::phoenix::nil_t + , typename T4 = ::phoenix::nil_t + , typename T5 = ::phoenix::nil_t + + #if BOOST_SPIRIT_CLOSURE_LIMIT > 6 + , typename T6 = ::phoenix::nil_t + , typename T7 = ::phoenix::nil_t + , typename T8 = ::phoenix::nil_t + + #if BOOST_SPIRIT_CLOSURE_LIMIT > 9 + , typename T9 = ::phoenix::nil_t + , typename T10 = ::phoenix::nil_t + , typename T11 = ::phoenix::nil_t + + #if BOOST_SPIRIT_CLOSURE_LIMIT > 12 + , typename T12 = ::phoenix::nil_t + , typename T13 = ::phoenix::nil_t + , typename T14 = ::phoenix::nil_t + + #endif + #endif + #endif + #endif + > + struct closure; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + diff --git a/boost/spirit/home/classic/attribute/parametric.hpp b/boost/spirit/home/classic/attribute/parametric.hpp new file mode 100644 index 0000000000..0c0b11ab09 --- /dev/null +++ b/boost/spirit/home/classic/attribute/parametric.hpp @@ -0,0 +1,144 @@ +/*============================================================================= + Copyright (c) 2001-2003 Joel de Guzman + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#ifndef BOOST_SPIRIT_PARAMETRIC_HPP +#define BOOST_SPIRIT_PARAMETRIC_HPP + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/core/composite/composite.hpp> +#include <boost/spirit/home/classic/core/primitives/primitives.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // f_chlit class [ functional version of chlit ] + // + /////////////////////////////////////////////////////////////////////////// + template <typename ChGenT> + struct f_chlit : public char_parser<f_chlit<ChGenT> > + { + f_chlit(ChGenT chgen_) + : chgen(chgen_) {} + + template <typename T> + bool test(T ch) const + { return ch == chgen(); } + + ChGenT chgen; + }; + + template <typename ChGenT> + inline f_chlit<ChGenT> + f_ch_p(ChGenT chgen) + { return f_chlit<ChGenT>(chgen); } + + /////////////////////////////////////////////////////////////////////////// + // + // f_range class [ functional version of range ] + // + /////////////////////////////////////////////////////////////////////////// + template <typename ChGenAT, typename ChGenBT> + struct f_range : public char_parser<f_range<ChGenAT, ChGenBT> > + { + f_range(ChGenAT first_, ChGenBT last_) + : first(first_), last(last_) + {} + + template <typename T> + bool test(T ch) const + { + BOOST_SPIRIT_ASSERT(first() <= last()); + return (ch >= first()) && (ch <= last()); + } + + ChGenAT first; + ChGenBT last; + }; + + template <typename ChGenAT, typename ChGenBT> + inline f_range<ChGenAT, ChGenBT> + f_range_p(ChGenAT first, ChGenBT last) + { return f_range<ChGenAT, ChGenBT>(first, last); } + + /////////////////////////////////////////////////////////////////////////// + // + // f_chseq class [ functional version of chseq ] + // + /////////////////////////////////////////////////////////////////////////// + template <typename IterGenAT, typename IterGenBT> + class f_chseq : public parser<f_chseq<IterGenAT, IterGenBT> > + { + public: + + typedef f_chseq<IterGenAT, IterGenBT> self_t; + + f_chseq(IterGenAT first_, IterGenBT last_) + : first(first_), last(last_) {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename parser_result<self_t, ScannerT>::type result_t; + return impl::string_parser_parse<result_t>(first(), last(), scan); + } + + private: + + IterGenAT first; + IterGenBT last; + }; + + template <typename IterGenAT, typename IterGenBT> + inline f_chseq<IterGenAT, IterGenBT> + f_chseq_p(IterGenAT first, IterGenBT last) + { return f_chseq<IterGenAT, IterGenBT>(first, last); } + + /////////////////////////////////////////////////////////////////////////// + // + // f_strlit class [ functional version of strlit ] + // + /////////////////////////////////////////////////////////////////////////// + template <typename IterGenAT, typename IterGenBT> + class f_strlit : public parser<f_strlit<IterGenAT, IterGenBT> > + { + public: + + typedef f_strlit<IterGenAT, IterGenBT> self_t; + + f_strlit(IterGenAT first, IterGenBT last) + : seq(first, last) {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename parser_result<self_t, ScannerT>::type result_t; + return impl::contiguous_parser_parse<result_t> + (seq, scan, scan); + } + + private: + + f_chseq<IterGenAT, IterGenBT> seq; + }; + + template <typename IterGenAT, typename IterGenBT> + inline f_strlit<IterGenAT, IterGenBT> + f_str_p(IterGenAT first, IterGenBT last) + { return f_strlit<IterGenAT, IterGenBT>(first, last); } + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif diff --git a/boost/spirit/home/classic/attribute/typeof.hpp b/boost/spirit/home/classic/attribute/typeof.hpp new file mode 100644 index 0000000000..16bbd102a0 --- /dev/null +++ b/boost/spirit/home/classic/attribute/typeof.hpp @@ -0,0 +1,67 @@ +/*============================================================================= + Copyright (c) 2006 Tobias Schwinger + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_ATTRIBUTE_TYPEOF_HPP) +#define BOOST_SPIRIT_ATTRIBUTE_TYPEOF_HPP + +#include <boost/typeof/typeof.hpp> + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/typeof.hpp> +#include <boost/spirit/home/classic/attribute/closure_fwd.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + // parametric.hpp + template<typename ChGenT> struct f_chlit; + template<typename ChGenAT, typename ChGenBT> struct f_range; + template<typename IterGenAT, typename IterGenBT> class f_chseq; + template<typename IterGenAT, typename IterGenBT> class f_strlit; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + + +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() + + +// parametric.hpp + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::f_chlit,1) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::f_range,2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::f_chseq,2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::f_strlit,2) + + +// closure.hpp (has forward header) + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::closure,BOOST_SPIRIT_CLOSURE_LIMIT) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::closure_context,1) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::init_closure_context,1) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::init_closure_parser,2) + + +#if BOOST_SPIRIT_CLOSURE_LIMIT > 12 +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::closure,12) +#endif +#if BOOST_SPIRIT_CLOSURE_LIMIT > 9 +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::closure, 9) +#endif +#if BOOST_SPIRIT_CLOSURE_LIMIT > 6 +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::closure, 6) +#endif +#if BOOST_SPIRIT_CLOSURE_LIMIT > 3 +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::closure, 3) +#endif + + + +#endif + diff --git a/boost/spirit/home/classic/core.hpp b/boost/spirit/home/classic/core.hpp new file mode 100644 index 0000000000..4f9d806f17 --- /dev/null +++ b/boost/spirit/home/classic/core.hpp @@ -0,0 +1,73 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001-2003 Daniel Nuffer + Copyright (c) 2001-2003 Hartmut Kaiser + Copyright (c) 2002-2003 Martin Wille + Copyright (c) 2002 Raghavendra Satish + Copyright (c) 2001 Bruce Florman + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_CORE_MAIN_HPP) +#define BOOST_SPIRIT_CORE_MAIN_HPP + +#include <boost/spirit/home/classic/version.hpp> +#include <boost/spirit/home/classic/debug.hpp> + +/////////////////////////////////////////////////////////////////////////////// +// +// Spirit.Core includes +// +/////////////////////////////////////////////////////////////////////////////// + +// Spirit.Core.Kernel +#include <boost/spirit/home/classic/core/config.hpp> +#include <boost/spirit/home/classic/core/nil.hpp> +#include <boost/spirit/home/classic/core/match.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> + +// Spirit.Core.Primitives +#include <boost/spirit/home/classic/core/primitives/primitives.hpp> +#include <boost/spirit/home/classic/core/primitives/numerics.hpp> + +// Spirit.Core.Scanner +#include <boost/spirit/home/classic/core/scanner/scanner.hpp> +#include <boost/spirit/home/classic/core/scanner/skipper.hpp> + +// Spirit.Core.NonTerminal +#include <boost/spirit/home/classic/core/non_terminal/subrule.hpp> +#include <boost/spirit/home/classic/core/non_terminal/rule.hpp> +#include <boost/spirit/home/classic/core/non_terminal/grammar.hpp> + +// Spirit.Core.Composite +#include <boost/spirit/home/classic/core/composite/actions.hpp> +#include <boost/spirit/home/classic/core/composite/composite.hpp> +#include <boost/spirit/home/classic/core/composite/directives.hpp> +#include <boost/spirit/home/classic/core/composite/epsilon.hpp> +#include <boost/spirit/home/classic/core/composite/sequence.hpp> +#include <boost/spirit/home/classic/core/composite/sequential_and.hpp> +#include <boost/spirit/home/classic/core/composite/sequential_or.hpp> +#include <boost/spirit/home/classic/core/composite/alternative.hpp> +#include <boost/spirit/home/classic/core/composite/difference.hpp> +#include <boost/spirit/home/classic/core/composite/intersection.hpp> +#include <boost/spirit/home/classic/core/composite/exclusive_or.hpp> +#include <boost/spirit/home/classic/core/composite/kleene_star.hpp> +#include <boost/spirit/home/classic/core/composite/positive.hpp> +#include <boost/spirit/home/classic/core/composite/optional.hpp> +#include <boost/spirit/home/classic/core/composite/list.hpp> +#include <boost/spirit/home/classic/core/composite/no_actions.hpp> + +// Deprecated interface includes +#include <boost/spirit/home/classic/actor/assign_actor.hpp> +#include <boost/spirit/home/classic/actor/push_back_actor.hpp> + +#if defined(BOOST_SPIRIT_DEBUG) + ////////////////////////////////// + #include <boost/spirit/home/classic/debug/parser_names.hpp> + +#endif // BOOST_SPIRIT_DEBUG + +#endif // BOOST_SPIRIT_CORE_MAIN_HPP + diff --git a/boost/spirit/home/classic/core/assert.hpp b/boost/spirit/home/classic/core/assert.hpp new file mode 100644 index 0000000000..47b1b39909 --- /dev/null +++ b/boost/spirit/home/classic/core/assert.hpp @@ -0,0 +1,38 @@ +/*============================================================================= + Copyright (c) 2001-2003 Joel de Guzman + Copyright (c) 2002-2003 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_ASSERT_HPP) +#define BOOST_SPIRIT_ASSERT_HPP + +#include <boost/config.hpp> +#include <boost/throw_exception.hpp> + +/////////////////////////////////////////////////////////////////////////////// +// +// BOOST_SPIRIT_ASSERT is used throughout the framework. It can be +// overridden by the user. If BOOST_SPIRIT_ASSERT_EXCEPTION is defined, +// then that will be thrown, otherwise, BOOST_SPIRIT_ASSERT simply turns +// into a plain BOOST_ASSERT() +// +/////////////////////////////////////////////////////////////////////////////// +#if !defined(BOOST_SPIRIT_ASSERT) +#if defined(NDEBUG) + #define BOOST_SPIRIT_ASSERT(x) +#elif defined (BOOST_SPIRIT_ASSERT_EXCEPTION) + #define BOOST_SPIRIT_ASSERT_AUX(f, l, x) BOOST_SPIRIT_ASSERT_AUX2(f, l, x) + #define BOOST_SPIRIT_ASSERT_AUX2(f, l, x) \ + do{ if (!(x)) boost::throw_exception( \ + BOOST_SPIRIT_ASSERT_EXCEPTION(f "(" #l "): " #x)); } while(0) + #define BOOST_SPIRIT_ASSERT(x) BOOST_SPIRIT_ASSERT_AUX(__FILE__, __LINE__, x) +#else + #include <boost/assert.hpp> + #define BOOST_SPIRIT_ASSERT(x) BOOST_ASSERT(x) +#endif +#endif // !defined(BOOST_SPIRIT_ASSERT) + +#endif // BOOST_SPIRIT_ASSERT_HPP diff --git a/boost/spirit/home/classic/core/composite/actions.hpp b/boost/spirit/home/classic/core/composite/actions.hpp new file mode 100644 index 0000000000..864211f710 --- /dev/null +++ b/boost/spirit/home/classic/core/composite/actions.hpp @@ -0,0 +1,136 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#ifndef BOOST_SPIRIT_ACTIONS_HPP +#define BOOST_SPIRIT_ACTIONS_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/core/composite/composite.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(push) +#pragma warning(disable:4512) //assignment operator could not be generated +#endif + + /////////////////////////////////////////////////////////////////////////// + // + // action class + // + // The action class binds a parser with a user defined semantic + // action. Instances of action are never created manually. Instead, + // action objects are typically created indirectly through + // expression templates of the form: + // + // p[f] + // + // where p is a parser and f is a function or functor. The semantic + // action may be a function or a functor. When the parser is + // successful, the actor calls the scanner's action_policy policy + // (see scanner.hpp): + // + // scan.do_action(actor, attribute, first, last); + // + // passing in these information: + // + // actor: The action's function or functor + // attribute: The match (returned by the parser) object's + // attribute (see match.hpp) + // first: Iterator pointing to the start of the matching + // portion of the input + // last: Iterator pointing to one past the end of the + // matching portion of the input + // + // It is the responsibility of the scanner's action_policy policy to + // dispatch the function or functor as it sees fit. The expected + // function or functor signature depends on the parser being + // wrapped. In general, if the attribute type of the parser being + // wrapped is a nil_t, the function or functor expect the signature: + // + // void func(Iterator first, Iterator last); // functions + // + // struct ftor // functors + // { + // void func(Iterator first, Iterator last) const; + // }; + // + // where Iterator is the type of the iterator that is being used and + // first and last are the iterators pointing to the matching portion + // of the input. + // + // If the attribute type of the parser being wrapped is not a nil_t, + // the function or functor usually expect the signature: + // + // void func(T val); // functions + // + // struct ftor // functors + // { + // void func(T val) const; + // }; + // + // where T is the attribute type and val is the attribute value + // returned by the parser being wrapped. + // + /////////////////////////////////////////////////////////////////////////// + template <typename ParserT, typename ActionT> + class action : public unary<ParserT, parser<action<ParserT, ActionT> > > + { + public: + + typedef action<ParserT, ActionT> self_t; + typedef action_parser_category parser_category_t; + typedef unary<ParserT, parser<self_t> > base_t; + typedef ActionT predicate_t; + + template <typename ScannerT> + struct result + { + typedef typename parser_result<ParserT, ScannerT>::type type; + }; + + action(ParserT const& p, ActionT const& a) + : base_t(p) + , actor(a) {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename ScannerT::iterator_t iterator_t; + typedef typename parser_result<self_t, ScannerT>::type result_t; + + scan.at_end(); // allow skipper to take effect + iterator_t save = scan.first; + result_t hit = this->subject().parse(scan); + if (hit) + { + typename result_t::return_t val = hit.value(); + scan.do_action(actor, val, save, scan.first); + } + return hit; + } + + ActionT const& predicate() const { return actor; } + + private: + + ActionT actor; + }; + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(pop) +#endif + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif diff --git a/boost/spirit/home/classic/core/composite/alternative.hpp b/boost/spirit/home/classic/core/composite/alternative.hpp new file mode 100644 index 0000000000..5e472a9a64 --- /dev/null +++ b/boost/spirit/home/classic/core/composite/alternative.hpp @@ -0,0 +1,147 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_ALTERNATIVE_HPP) +#define BOOST_SPIRIT_ALTERNATIVE_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/core/primitives/primitives.hpp> +#include <boost/spirit/home/classic/core/composite/composite.hpp> +#include <boost/spirit/home/classic/meta/as_parser.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // alternative class + // + // Handles expressions of the form: + // + // a | b + // + // where a and b are parsers. The expression returns a composite + // parser that matches a or b. One (not both) of the operands may + // be a literal char, wchar_t or a primitive string char const*, + // wchar_t const*. + // + // The expression is short circuit evaluated. b is never touched + // when a is returns a successful match. + // + /////////////////////////////////////////////////////////////////////////// + struct alternative_parser_gen; + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(push) +#pragma warning(disable:4512) //assignment operator could not be generated +#endif + + template <typename A, typename B> + struct alternative + : public binary<A, B, parser<alternative<A, B> > > + { + typedef alternative<A, B> self_t; + typedef binary_parser_category parser_category_t; + typedef alternative_parser_gen parser_generator_t; + typedef binary<A, B, parser<self_t> > base_t; + + alternative(A const& a, B const& b) + : base_t(a, b) {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename parser_result<self_t, ScannerT>::type result_t; + typedef typename ScannerT::iterator_t iterator_t; + { // scope for save + iterator_t save = scan.first; + if (result_t hit = this->left().parse(scan)) + return hit; + scan.first = save; + } + return this->right().parse(scan); + } + }; + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(pop) +#endif + + struct alternative_parser_gen + { + template <typename A, typename B> + struct result + { + typedef + alternative< + typename as_parser<A>::type + , typename as_parser<B>::type + > + type; + }; + + template <typename A, typename B> + static alternative< + typename as_parser<A>::type + , typename as_parser<B>::type + > + generate(A const& a, B const& b) + { + return alternative<BOOST_DEDUCED_TYPENAME as_parser<A>::type, + BOOST_DEDUCED_TYPENAME as_parser<B>::type> + (as_parser<A>::convert(a), as_parser<B>::convert(b)); + } + }; + + template <typename A, typename B> + alternative<A, B> + operator|(parser<A> const& a, parser<B> const& b); + + template <typename A> + alternative<A, chlit<char> > + operator|(parser<A> const& a, char b); + + template <typename B> + alternative<chlit<char>, B> + operator|(char a, parser<B> const& b); + + template <typename A> + alternative<A, strlit<char const*> > + operator|(parser<A> const& a, char const* b); + + template <typename B> + alternative<strlit<char const*>, B> + operator|(char const* a, parser<B> const& b); + + template <typename A> + alternative<A, chlit<wchar_t> > + operator|(parser<A> const& a, wchar_t b); + + template <typename B> + alternative<chlit<wchar_t>, B> + operator|(wchar_t a, parser<B> const& b); + + template <typename A> + alternative<A, strlit<wchar_t const*> > + operator|(parser<A> const& a, wchar_t const* b); + + template <typename B> + alternative<strlit<wchar_t const*>, B> + operator|(wchar_t const* a, parser<B> const& b); + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + +#include <boost/spirit/home/classic/core/composite/impl/alternative.ipp> diff --git a/boost/spirit/home/classic/core/composite/composite.hpp b/boost/spirit/home/classic/core/composite/composite.hpp new file mode 100644 index 0000000000..b156cab198 --- /dev/null +++ b/boost/spirit/home/classic/core/composite/composite.hpp @@ -0,0 +1,151 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_COMPOSITE_HPP) +#define BOOST_SPIRIT_COMPOSITE_HPP + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/compressed_pair.hpp> +#include <boost/spirit/home/classic/namespace.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(push) +#pragma warning(disable:4512) //assignment operator could not be generated +#endif + + /////////////////////////////////////////////////////////////////////////// + // + // unary class. + // + // Composite class composed of a single subject. This template class + // is parameterized by the subject type S and a base class to + // inherit from, BaseT. The unary class is meant to be a base class + // to inherit from. The inheritance structure, given the BaseT + // template parameter places the unary class in the middle of a + // linear, single parent hierarchy. For instance, given a class S + // and a base class B, a class D can derive from unary: + // + // struct D : public unary<S, B> {...}; + // + // The inheritance structure is thus: + // + // B + // | + // unary (has S) + // | + // D + // + // The subject can be accessed from the derived class D as: + // this->subject(); + // + // Typically, the subject S is specified as typename S::embed_t. + // embed_t specifies how the subject is embedded in the composite + // (See parser.hpp for details). + // + /////////////////////////////////////////////////////////////////////////// + template <typename S, typename BaseT> + class unary : public BaseT + { + public: + + typedef BaseT base_t; + typedef typename boost::call_traits<S>::param_type param_t; + typedef typename boost::call_traits<S>::const_reference return_t; + typedef S subject_t; + typedef typename S::embed_t subject_embed_t; + + unary(param_t subj_) + : base_t(), subj(subj_) {} + + unary(BaseT const& base, param_t subj_) + : base_t(base), subj(subj_) {} + + return_t + subject() const + { return subj; } + + private: + + subject_embed_t subj; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // binary class. + // + // Composite class composed of a pair (left and right). This + // template class is parameterized by the left and right subject + // types A and B and a base class to inherit from, BaseT. The binary + // class is meant to be a base class to inherit from. The + // inheritance structure, given the BaseT template parameter places + // the binary class in the middle of a linear, single parent + // hierarchy. For instance, given classes X and Y and a base class + // B, a class D can derive from binary: + // + // struct D : public binary<X, Y, B> {...}; + // + // The inheritance structure is thus: + // + // B + // | + // binary (has X and Y) + // | + // D + // + // The left and right subjects can be accessed from the derived + // class D as: this->left(); and this->right(); + // + // Typically, the pairs X and Y are specified as typename X::embed_t + // and typename Y::embed_t. embed_t specifies how the subject is + // embedded in the composite (See parser.hpp for details). + // + /////////////////////////////////////////////////////////////////////////////// + template <typename A, typename B, typename BaseT> + class binary : public BaseT + { + public: + + typedef BaseT base_t; + typedef typename boost::call_traits<A>::param_type left_param_t; + typedef typename boost::call_traits<A>::const_reference left_return_t; + typedef typename boost::call_traits<B>::param_type right_param_t; + typedef typename boost::call_traits<B>::const_reference right_return_t; + typedef A left_t; + typedef typename A::embed_t left_embed_t; + typedef B right_t; + typedef typename B::embed_t right_embed_t; + + binary(left_param_t a, right_param_t b) + : base_t(), subj(a, b) {} + + left_return_t + left() const + { return subj.first(); } + + right_return_t + right() const + { return subj.second(); } + + private: + + boost::compressed_pair<left_embed_t, right_embed_t> subj; + }; + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(pop) +#endif + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif diff --git a/boost/spirit/home/classic/core/composite/difference.hpp b/boost/spirit/home/classic/core/composite/difference.hpp new file mode 100644 index 0000000000..7d1cb1433d --- /dev/null +++ b/boost/spirit/home/classic/core/composite/difference.hpp @@ -0,0 +1,150 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_DIFFERENCE_HPP) +#define BOOST_SPIRIT_DIFFERENCE_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/core/primitives/primitives.hpp> +#include <boost/spirit/home/classic/core/composite/composite.hpp> +#include <boost/spirit/home/classic/meta/as_parser.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // difference: a - b; Matches a but not b + // + // Handles expressions of the form: + // + // a - b + // + // where a and b are parsers. The expression returns a composite + // parser that matches a but not b. One (not both) of the operands + // may be a literal char, wchar_t or a primitive string char const*, + // wchar_t const*. + // + /////////////////////////////////////////////////////////////////////////// + struct difference_parser_gen; + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(push) +#pragma warning(disable:4512) //assignment operator could not be generated +#endif + + template <typename A, typename B> + struct difference + : public binary<A, B, parser<difference<A, B> > > + { + typedef difference<A, B> self_t; + typedef binary_parser_category parser_category_t; + typedef difference_parser_gen parser_generator_t; + typedef binary<A, B, parser<self_t> > base_t; + + difference(A const& a, B const& b) + : base_t(a, b) {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename parser_result<self_t, ScannerT>::type result_t; + typedef typename ScannerT::iterator_t iterator_t; + iterator_t save = scan.first; + if (result_t hl = this->left().parse(scan)) + { + std::swap(save, scan.first); + result_t hr = this->right().parse(scan); + if (!hr || (hr.length() < hl.length())) + { + scan.first = save; + return hl; + } + } + + return scan.no_match(); + } + }; + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(pop) +#endif + + struct difference_parser_gen + { + template <typename A, typename B> + struct result + { + typedef + difference< + typename as_parser<A>::type + , typename as_parser<B>::type + > + type; + }; + + template <typename A, typename B> + static difference< + typename as_parser<A>::type + , typename as_parser<B>::type + > + generate(A const& a, B const& b) + { + return difference<BOOST_DEDUCED_TYPENAME as_parser<A>::type, + BOOST_DEDUCED_TYPENAME as_parser<B>::type> + (as_parser<A>::convert(a), as_parser<B>::convert(b)); + } + }; + + template <typename A, typename B> + difference<A, B> + operator-(parser<A> const& a, parser<B> const& b); + + template <typename A> + difference<A, chlit<char> > + operator-(parser<A> const& a, char b); + + template <typename B> + difference<chlit<char>, B> + operator-(char a, parser<B> const& b); + + template <typename A> + difference<A, strlit<char const*> > + operator-(parser<A> const& a, char const* b); + + template <typename B> + difference<strlit<char const*>, B> + operator-(char const* a, parser<B> const& b); + + template <typename A> + difference<A, chlit<wchar_t> > + operator-(parser<A> const& a, wchar_t b); + + template <typename B> + difference<chlit<wchar_t>, B> + operator-(wchar_t a, parser<B> const& b); + + template <typename A> + difference<A, strlit<wchar_t const*> > + operator-(parser<A> const& a, wchar_t const* b); + + template <typename B> + difference<strlit<wchar_t const*>, B> + operator-(wchar_t const* a, parser<B> const& b); + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + +#include <boost/spirit/home/classic/core/composite/impl/difference.ipp> diff --git a/boost/spirit/home/classic/core/composite/directives.hpp b/boost/spirit/home/classic/core/composite/directives.hpp new file mode 100644 index 0000000000..a66efa281f --- /dev/null +++ b/boost/spirit/home/classic/core/composite/directives.hpp @@ -0,0 +1,607 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 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) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_DIRECTIVES_HPP) +#define BOOST_SPIRIT_DIRECTIVES_HPP + +/////////////////////////////////////////////////////////////////////////////// +#include <algorithm> + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/core/scanner/skipper.hpp> +#include <boost/spirit/home/classic/core/primitives/primitives.hpp> +#include <boost/spirit/home/classic/core/composite/composite.hpp> +#include <boost/spirit/home/classic/core/composite/impl/directives.ipp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // contiguous class + // + /////////////////////////////////////////////////////////////////////////// + struct lexeme_parser_gen; + + template <typename ParserT> + struct contiguous + : public unary<ParserT, parser<contiguous<ParserT> > > + { + typedef contiguous<ParserT> self_t; + typedef unary_parser_category parser_category_t; + typedef lexeme_parser_gen parser_generator_t; + typedef unary<ParserT, parser<self_t> > base_t; + + template <typename ScannerT> + struct result + { + typedef typename parser_result<ParserT, ScannerT>::type type; + }; + + contiguous(ParserT const& p) + : base_t(p) {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename parser_result<self_t, ScannerT>::type result_t; + return impl::contiguous_parser_parse<result_t> + (this->subject(), scan, scan); + } + }; + + struct lexeme_parser_gen + { + template <typename ParserT> + struct result { + + typedef contiguous<ParserT> type; + }; + + template <typename ParserT> + static contiguous<ParserT> + generate(parser<ParserT> const& subject) + { + return contiguous<ParserT>(subject.derived()); + } + + template <typename ParserT> + contiguous<ParserT> + operator[](parser<ParserT> const& subject) const + { + return contiguous<ParserT>(subject.derived()); + } + }; + + ////////////////////////////////// + const lexeme_parser_gen lexeme_d = lexeme_parser_gen(); + + /////////////////////////////////////////////////////////////////////////// + // + // lexeme_scanner + // + // Given a Scanner, return the correct scanner type that + // the lexeme_d uses. Scanner is assumed to be a phrase + // level scanner (see skipper.hpp) + // + /////////////////////////////////////////////////////////////////////////// + template <typename ScannerT> + struct lexeme_scanner + { + typedef scanner_policies< + no_skipper_iteration_policy< + typename ScannerT::iteration_policy_t>, + typename ScannerT::match_policy_t, + typename ScannerT::action_policy_t + > policies_t; + + typedef typename + rebind_scanner_policies<ScannerT, policies_t>::type type; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // inhibit_case_iteration_policy class + // + /////////////////////////////////////////////////////////////////////////// + template <typename BaseT> + struct inhibit_case_iteration_policy : public BaseT + { + typedef BaseT base_t; + + inhibit_case_iteration_policy() + : BaseT() {} + + template <typename PolicyT> + inhibit_case_iteration_policy(PolicyT const& other) + : BaseT(other) {} + + template <typename CharT> + CharT filter(CharT ch) const + { return impl::tolower_(ch); } + }; + + /////////////////////////////////////////////////////////////////////////// + // + // inhibit_case class + // + /////////////////////////////////////////////////////////////////////////// + struct inhibit_case_parser_gen; + + template <typename ParserT> + struct inhibit_case + : public unary<ParserT, parser<inhibit_case<ParserT> > > + { + typedef inhibit_case<ParserT> self_t; + typedef unary_parser_category parser_category_t; + typedef inhibit_case_parser_gen parser_generator_t; + typedef unary<ParserT, parser<self_t> > base_t; + + template <typename ScannerT> + struct result + { + typedef typename parser_result<ParserT, ScannerT>::type type; + }; + + inhibit_case(ParserT const& p) + : base_t(p) {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename parser_result<self_t, ScannerT>::type result_t; + return impl::inhibit_case_parser_parse<result_t> + (this->subject(), scan, scan); + } + }; + + template <int N> + struct inhibit_case_parser_gen_base + { + // This hack is needed to make borland happy. + // If these member operators were defined in the + // inhibit_case_parser_gen class, or if this class + // is non-templated, borland ICEs. + + static inhibit_case<strlit<char const*> > + generate(char const* str) + { return inhibit_case<strlit<char const*> >(str); } + + static inhibit_case<strlit<wchar_t const*> > + generate(wchar_t const* str) + { return inhibit_case<strlit<wchar_t const*> >(str); } + + static inhibit_case<chlit<char> > + generate(char ch) + { return inhibit_case<chlit<char> >(ch); } + + static inhibit_case<chlit<wchar_t> > + generate(wchar_t ch) + { return inhibit_case<chlit<wchar_t> >(ch); } + + template <typename ParserT> + static inhibit_case<ParserT> + generate(parser<ParserT> const& subject) + { return inhibit_case<ParserT>(subject.derived()); } + + inhibit_case<strlit<char const*> > + operator[](char const* str) const + { return inhibit_case<strlit<char const*> >(str); } + + inhibit_case<strlit<wchar_t const*> > + operator[](wchar_t const* str) const + { return inhibit_case<strlit<wchar_t const*> >(str); } + + inhibit_case<chlit<char> > + operator[](char ch) const + { return inhibit_case<chlit<char> >(ch); } + + inhibit_case<chlit<wchar_t> > + operator[](wchar_t ch) const + { return inhibit_case<chlit<wchar_t> >(ch); } + + template <typename ParserT> + inhibit_case<ParserT> + operator[](parser<ParserT> const& subject) const + { return inhibit_case<ParserT>(subject.derived()); } + }; + + ////////////////////////////////// + struct inhibit_case_parser_gen : public inhibit_case_parser_gen_base<0> + { + inhibit_case_parser_gen() {} + }; + + ////////////////////////////////// + // Depracated + const inhibit_case_parser_gen nocase_d = inhibit_case_parser_gen(); + + // Preferred syntax + const inhibit_case_parser_gen as_lower_d = inhibit_case_parser_gen(); + + /////////////////////////////////////////////////////////////////////////// + // + // as_lower_scanner + // + // Given a Scanner, return the correct scanner type that + // the as_lower_d uses. Scanner is assumed to be a scanner + // with an inhibit_case_iteration_policy. + // + /////////////////////////////////////////////////////////////////////////// + template <typename ScannerT> + struct as_lower_scanner + { + typedef scanner_policies< + inhibit_case_iteration_policy< + typename ScannerT::iteration_policy_t>, + typename ScannerT::match_policy_t, + typename ScannerT::action_policy_t + > policies_t; + + typedef typename + rebind_scanner_policies<ScannerT, policies_t>::type type; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // longest_alternative class + // + /////////////////////////////////////////////////////////////////////////// + struct longest_parser_gen; + + template <typename A, typename B> + struct longest_alternative + : public binary<A, B, parser<longest_alternative<A, B> > > + { + typedef longest_alternative<A, B> self_t; + typedef binary_parser_category parser_category_t; + typedef longest_parser_gen parser_generator_t; + typedef binary<A, B, parser<self_t> > base_t; + + longest_alternative(A const& a, B const& b) + : base_t(a, b) {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename parser_result<self_t, ScannerT>::type result_t; + typename ScannerT::iterator_t save = scan.first; + result_t l = this->left().parse(scan); + std::swap(scan.first, save); + result_t r = this->right().parse(scan); + + if (l || r) + { + if (l.length() > r.length()) + { + scan.first = save; + return l; + } + return r; + } + + return scan.no_match(); + } + }; + + struct longest_parser_gen + { + template <typename A, typename B> + struct result { + + typedef typename + impl::to_longest_alternative<alternative<A, B> >::result_t + type; + }; + + template <typename A, typename B> + static typename + impl::to_longest_alternative<alternative<A, B> >::result_t + generate(alternative<A, B> const& alt) + { + return impl::to_longest_alternative<alternative<A, B> >:: + convert(alt); + } + + //'generate' for binary composite + template <typename A, typename B> + static + longest_alternative<A, B> + generate(A const &left, B const &right) + { + return longest_alternative<A, B>(left, right); + } + + template <typename A, typename B> + typename impl::to_longest_alternative<alternative<A, B> >::result_t + operator[](alternative<A, B> const& alt) const + { + return impl::to_longest_alternative<alternative<A, B> >:: + convert(alt); + } + }; + + const longest_parser_gen longest_d = longest_parser_gen(); + + /////////////////////////////////////////////////////////////////////////// + // + // shortest_alternative class + // + /////////////////////////////////////////////////////////////////////////// + struct shortest_parser_gen; + + template <typename A, typename B> + struct shortest_alternative + : public binary<A, B, parser<shortest_alternative<A, B> > > + { + typedef shortest_alternative<A, B> self_t; + typedef binary_parser_category parser_category_t; + typedef shortest_parser_gen parser_generator_t; + typedef binary<A, B, parser<self_t> > base_t; + + shortest_alternative(A const& a, B const& b) + : base_t(a, b) {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename parser_result<self_t, ScannerT>::type result_t; + typename ScannerT::iterator_t save = scan.first; + result_t l = this->left().parse(scan); + std::swap(scan.first, save); + result_t r = this->right().parse(scan); + + if (l || r) + { + if ((l.length() < r.length() && l) || !r) + { + scan.first = save; + return l; + } + return r; + } + + return scan.no_match(); + } + }; + + struct shortest_parser_gen + { + template <typename A, typename B> + struct result { + + typedef typename + impl::to_shortest_alternative<alternative<A, B> >::result_t + type; + }; + + template <typename A, typename B> + static typename + impl::to_shortest_alternative<alternative<A, B> >::result_t + generate(alternative<A, B> const& alt) + { + return impl::to_shortest_alternative<alternative<A, B> >:: + convert(alt); + } + + //'generate' for binary composite + template <typename A, typename B> + static + shortest_alternative<A, B> + generate(A const &left, B const &right) + { + return shortest_alternative<A, B>(left, right); + } + + template <typename A, typename B> + typename impl::to_shortest_alternative<alternative<A, B> >::result_t + operator[](alternative<A, B> const& alt) const + { + return impl::to_shortest_alternative<alternative<A, B> >:: + convert(alt); + } + }; + + const shortest_parser_gen shortest_d = shortest_parser_gen(); + + /////////////////////////////////////////////////////////////////////////// + // + // min_bounded class + // + /////////////////////////////////////////////////////////////////////////// + template <typename BoundsT> + struct min_bounded_gen; + + template <typename ParserT, typename BoundsT> + struct min_bounded + : public unary<ParserT, parser<min_bounded<ParserT, BoundsT> > > + { + typedef min_bounded<ParserT, BoundsT> self_t; + typedef unary_parser_category parser_category_t; + typedef min_bounded_gen<BoundsT> parser_generator_t; + typedef unary<ParserT, parser<self_t> > base_t; + + template <typename ScannerT> + struct result + { + typedef typename parser_result<ParserT, ScannerT>::type type; + }; + + min_bounded(ParserT const& p, BoundsT const& min__) + : base_t(p) + , min_(min__) {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename parser_result<self_t, ScannerT>::type result_t; + result_t hit = this->subject().parse(scan); + if (hit.has_valid_attribute() && hit.value() < min_) + return scan.no_match(); + return hit; + } + + BoundsT min_; + }; + + template <typename BoundsT> + struct min_bounded_gen + { + min_bounded_gen(BoundsT const& min__) + : min_(min__) {} + + template <typename DerivedT> + min_bounded<DerivedT, BoundsT> + operator[](parser<DerivedT> const& p) const + { return min_bounded<DerivedT, BoundsT>(p.derived(), min_); } + + BoundsT min_; + }; + + template <typename BoundsT> + inline min_bounded_gen<BoundsT> + min_limit_d(BoundsT const& min_) + { return min_bounded_gen<BoundsT>(min_); } + + /////////////////////////////////////////////////////////////////////////// + // + // max_bounded class + // + /////////////////////////////////////////////////////////////////////////// + template <typename BoundsT> + struct max_bounded_gen; + + template <typename ParserT, typename BoundsT> + struct max_bounded + : public unary<ParserT, parser<max_bounded<ParserT, BoundsT> > > + { + typedef max_bounded<ParserT, BoundsT> self_t; + typedef unary_parser_category parser_category_t; + typedef max_bounded_gen<BoundsT> parser_generator_t; + typedef unary<ParserT, parser<self_t> > base_t; + + template <typename ScannerT> + struct result + { + typedef typename parser_result<ParserT, ScannerT>::type type; + }; + + max_bounded(ParserT const& p, BoundsT const& max__) + : base_t(p) + , max_(max__) {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename parser_result<self_t, ScannerT>::type result_t; + result_t hit = this->subject().parse(scan); + if (hit.has_valid_attribute() && hit.value() > max_) + return scan.no_match(); + return hit; + } + + BoundsT max_; + }; + + template <typename BoundsT> + struct max_bounded_gen + { + max_bounded_gen(BoundsT const& max__) + : max_(max__) {} + + template <typename DerivedT> + max_bounded<DerivedT, BoundsT> + operator[](parser<DerivedT> const& p) const + { return max_bounded<DerivedT, BoundsT>(p.derived(), max_); } + + BoundsT max_; + }; + + ////////////////////////////////// + template <typename BoundsT> + inline max_bounded_gen<BoundsT> + max_limit_d(BoundsT const& max_) + { return max_bounded_gen<BoundsT>(max_); } + + /////////////////////////////////////////////////////////////////////////// + // + // bounded class + // + /////////////////////////////////////////////////////////////////////////// + template <typename BoundsT> + struct bounded_gen; + + template <typename ParserT, typename BoundsT> + struct bounded + : public unary<ParserT, parser<bounded<ParserT, BoundsT> > > + { + typedef bounded<ParserT, BoundsT> self_t; + typedef unary_parser_category parser_category_t; + typedef bounded_gen<BoundsT> parser_generator_t; + typedef unary<ParserT, parser<self_t> > base_t; + + template <typename ScannerT> + struct result + { + typedef typename parser_result<ParserT, ScannerT>::type type; + }; + + bounded(ParserT const& p, BoundsT const& min__, BoundsT const& max__) + : base_t(p) + , min_(min__) + , max_(max__) {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename parser_result<self_t, ScannerT>::type result_t; + result_t hit = this->subject().parse(scan); + if (hit.has_valid_attribute() && + (hit.value() < min_ || hit.value() > max_)) + return scan.no_match(); + return hit; + } + + BoundsT min_, max_; + }; + + template <typename BoundsT> + struct bounded_gen + { + bounded_gen(BoundsT const& min__, BoundsT const& max__) + : min_(min__) + , max_(max__) {} + + template <typename DerivedT> + bounded<DerivedT, BoundsT> + operator[](parser<DerivedT> const& p) const + { return bounded<DerivedT, BoundsT>(p.derived(), min_, max_); } + + BoundsT min_, max_; + }; + + template <typename BoundsT> + inline bounded_gen<BoundsT> + limit_d(BoundsT const& min_, BoundsT const& max_) + { return bounded_gen<BoundsT>(min_, max_); } + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + diff --git a/boost/spirit/home/classic/core/composite/epsilon.hpp b/boost/spirit/home/classic/core/composite/epsilon.hpp new file mode 100644 index 0000000000..f9654e2e51 --- /dev/null +++ b/boost/spirit/home/classic/core/composite/epsilon.hpp @@ -0,0 +1,276 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2002-2003 Martin Wille + 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_EPSILON_HPP +#define BOOST_SPIRIT_EPSILON_HPP + +//////////////////////////////////////////////////////////////////////////////// +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/meta/parser_traits.hpp> +#include <boost/spirit/home/classic/core/composite/composite.hpp> +#include <boost/spirit/home/classic/core/composite/no_actions.hpp> + +//////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// +// condition_parser class +// +// handles expresions of the form +// +// epsilon_p(cond) +// +// where cond is a function or a functor that returns a value suitable +// to be used in boolean context. The expression returns a parser that +// returns an empty match when the condition evaluates to true. +// +/////////////////////////////////////////////////////////////////////////////// + template <typename CondT, bool positive_ = true> + struct condition_parser : parser<condition_parser<CondT, positive_> > + { + typedef condition_parser<CondT, positive_> self_t; + + // not explicit! (needed for implementation of if_p et al.) + condition_parser(CondT const& cond_) : cond(cond_) {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + if (positive_ == bool(cond())) // allow cond to return int + return scan.empty_match(); + else + return scan.no_match(); + } + + condition_parser<CondT, !positive_> + negate() const + { return condition_parser<CondT, !positive_>(cond); } + + private: + + CondT cond; + }; + +#if BOOST_WORKAROUND(BOOST_MSVC, == 1310) || \ + BOOST_WORKAROUND(BOOST_MSVC, == 1400) || \ + BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580) +// VC 7.1, VC8 and Sun CC <= 5.8 do not support general +// expressions of non-type template parameters in instantiations + template <typename CondT> + inline condition_parser<CondT, false> + operator~(condition_parser<CondT, true> const& p) + { return p.negate(); } + + template <typename CondT> + inline condition_parser<CondT, true> + operator~(condition_parser<CondT, false> const& p) + { return p.negate(); } +#else // BOOST_WORKAROUND(BOOST_MSVC, == 1310) || == 1400 + template <typename CondT, bool positive> + inline condition_parser<CondT, !positive> + operator~(condition_parser<CondT, positive> const& p) + { return p.negate(); } +#endif // BOOST_WORKAROUND(BOOST_MSVC, == 1310) || == 1400 + +/////////////////////////////////////////////////////////////////////////////// +// +// empty_match_parser class +// +// handles expressions of the form +// epsilon_p(subject) +// where subject is a parser. The expresion returns a composite +// parser that returns an empty match if the subject parser matches. +// +/////////////////////////////////////////////////////////////////////////////// + struct empty_match_parser_gen; + struct negated_empty_match_parser_gen; + + template <typename SubjectT> + struct negated_empty_match_parser; // Forward declaration + + template<typename SubjectT> + struct empty_match_parser + : unary<SubjectT, parser<empty_match_parser<SubjectT> > > + { + typedef empty_match_parser<SubjectT> self_t; + typedef unary<SubjectT, parser<self_t> > base_t; + typedef unary_parser_category parser_category_t; + typedef empty_match_parser_gen parser_genererator_t; + typedef self_t embed_t; + + explicit empty_match_parser(SubjectT const& p) : base_t(p) {} + + template <typename ScannerT> + struct result + { typedef typename match_result<ScannerT, nil_t>::type type; }; + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typename ScannerT::iterator_t save(scan.first); + + typedef typename no_actions_scanner<ScannerT>::policies_t + policies_t; + + bool matches = this->subject().parse( + scan.change_policies(policies_t(scan))); + if (matches) + { + scan.first = save; // reset the position + return scan.empty_match(); + } + else + { + return scan.no_match(); + } + } + + negated_empty_match_parser<SubjectT> + negate() const + { return negated_empty_match_parser<SubjectT>(this->subject()); } + }; + + template<typename SubjectT> + struct negated_empty_match_parser + : public unary<SubjectT, parser<negated_empty_match_parser<SubjectT> > > + { + typedef negated_empty_match_parser<SubjectT> self_t; + typedef unary<SubjectT, parser<self_t> > base_t; + typedef unary_parser_category parser_category_t; + typedef negated_empty_match_parser_gen parser_genererator_t; + + explicit negated_empty_match_parser(SubjectT const& p) : base_t(p) {} + + template <typename ScannerT> + struct result + { typedef typename match_result<ScannerT, nil_t>::type type; }; + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typename ScannerT::iterator_t save(scan.first); + + typedef typename no_actions_scanner<ScannerT>::policies_t + policies_t; + + bool matches = this->subject().parse( + scan.change_policies(policies_t(scan))); + if (!matches) + { + scan.first = save; // reset the position + return scan.empty_match(); + } + else + { + return scan.no_match(); + } + } + + empty_match_parser<SubjectT> + negate() const + { return empty_match_parser<SubjectT>(this->subject()); } + }; + + struct empty_match_parser_gen + { + template <typename SubjectT> + struct result + { typedef empty_match_parser<SubjectT> type; }; + + template <typename SubjectT> + static empty_match_parser<SubjectT> + generate(parser<SubjectT> const& subject) + { return empty_match_parser<SubjectT>(subject.derived()); } + }; + + struct negated_empty_match_parser_gen + { + template <typename SubjectT> + struct result + { typedef negated_empty_match_parser<SubjectT> type; }; + + template <typename SubjectT> + static negated_empty_match_parser<SubjectT> + generate(parser<SubjectT> const& subject) + { return negated_empty_match_parser<SubjectT>(subject.derived()); } + }; + + ////////////////////////////// + template <typename SubjectT> + inline negated_empty_match_parser<SubjectT> + operator~(empty_match_parser<SubjectT> const& p) + { return p.negate(); } + + template <typename SubjectT> + inline empty_match_parser<SubjectT> + operator~(negated_empty_match_parser<SubjectT> const& p) + { return p.negate(); } + +/////////////////////////////////////////////////////////////////////////////// +// +// epsilon_ parser and parser generator class +// +// Operates as primitive parser that always matches an empty sequence. +// +// Also operates as a parser generator. According to the type of the +// argument an instance of empty_match_parser<> (when the argument is +// a parser) or condition_parser<> (when the argument is not a parser) +// is returned by operator(). +// +/////////////////////////////////////////////////////////////////////////////// + namespace impl + { + template <typename SubjectT> + struct epsilon_selector + { + typedef typename as_parser<SubjectT>::type subject_t; + typedef typename + mpl::if_< + is_parser<subject_t> + ,empty_match_parser<subject_t> + ,condition_parser<subject_t> + >::type type; + }; + } + + struct epsilon_parser : public parser<epsilon_parser> + { + typedef epsilon_parser self_t; + + epsilon_parser() {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { return scan.empty_match(); } + + template <typename SubjectT> + typename impl::epsilon_selector<SubjectT>::type + operator()(SubjectT const& subject) const + { + typedef typename impl::epsilon_selector<SubjectT>::type result_t; + return result_t(subject); + } + }; + + epsilon_parser const epsilon_p = epsilon_parser(); + epsilon_parser const eps_p = epsilon_parser(); + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif diff --git a/boost/spirit/home/classic/core/composite/exclusive_or.hpp b/boost/spirit/home/classic/core/composite/exclusive_or.hpp new file mode 100644 index 0000000000..69d4859b00 --- /dev/null +++ b/boost/spirit/home/classic/core/composite/exclusive_or.hpp @@ -0,0 +1,142 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_EXCLUSIVE_OR_HPP) +#define BOOST_SPIRIT_EXCLUSIVE_OR_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/core/primitives/primitives.hpp> +#include <boost/spirit/home/classic/core/composite/composite.hpp> +#include <boost/spirit/home/classic/meta/as_parser.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // exclusive_or class + // + // Handles expressions of the form: + // + // a ^ b + // + // where a and b are parsers. The expression returns a composite + // parser that matches a or b but not both. One (not both) of the + // operands may be a literal char, wchar_t or a primitive string + // char const*, wchar_t const*. + // + /////////////////////////////////////////////////////////////////////////// + struct exclusive_or_parser_gen; + + template <typename A, typename B> + struct exclusive_or + : public binary<A, B, parser<exclusive_or<A, B> > > + { + typedef exclusive_or<A, B> self_t; + typedef binary_parser_category parser_category_t; + typedef exclusive_or_parser_gen parser_generator_t; + typedef binary<A, B, parser<self_t> > base_t; + + exclusive_or(A const& a, B const& b) + : base_t(a, b) {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename parser_result<self_t, ScannerT>::type result_t; + typedef typename ScannerT::iterator_t iterator_t; + + iterator_t save = scan.first; + result_t l = this->left().parse(scan); + std::swap(save, scan.first); + result_t r = this->right().parse(scan); + + if (l ? !bool(r) : bool(r)) + { + if (l) + scan.first = save; + return l ? l : r; + } + + return scan.no_match(); + } + }; + + struct exclusive_or_parser_gen + { + template <typename A, typename B> + struct result + { + typedef + exclusive_or< + typename as_parser<A>::type + , typename as_parser<B>::type + > + type; + }; + + template <typename A, typename B> + static exclusive_or< + typename as_parser<A>::type + , typename as_parser<B>::type + > + generate(A const& a, B const& b) + { + return exclusive_or<BOOST_DEDUCED_TYPENAME as_parser<A>::type, + BOOST_DEDUCED_TYPENAME as_parser<B>::type> + (as_parser<A>::convert(a), as_parser<B>::convert(b)); + } + }; + + template <typename A, typename B> + exclusive_or<A, B> + operator^(parser<A> const& a, parser<B> const& b); + + template <typename A> + exclusive_or<A, chlit<char> > + operator^(parser<A> const& a, char b); + + template <typename B> + exclusive_or<chlit<char>, B> + operator^(char a, parser<B> const& b); + + template <typename A> + exclusive_or<A, strlit<char const*> > + operator^(parser<A> const& a, char const* b); + + template <typename B> + exclusive_or<strlit<char const*>, B> + operator^(char const* a, parser<B> const& b); + + template <typename A> + exclusive_or<A, chlit<wchar_t> > + operator^(parser<A> const& a, wchar_t b); + + template <typename B> + exclusive_or<chlit<wchar_t>, B> + operator^(wchar_t a, parser<B> const& b); + + template <typename A> + exclusive_or<A, strlit<wchar_t const*> > + operator^(parser<A> const& a, wchar_t const* b); + + template <typename B> + exclusive_or<strlit<wchar_t const*>, B> + operator^(wchar_t const* a, parser<B> const& b); + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + +#include <boost/spirit/home/classic/core/composite/impl/exclusive_or.ipp> diff --git a/boost/spirit/home/classic/core/composite/impl/alternative.ipp b/boost/spirit/home/classic/core/composite/impl/alternative.ipp new file mode 100644 index 0000000000..7a7599b85c --- /dev/null +++ b/boost/spirit/home/classic/core/composite/impl/alternative.ipp @@ -0,0 +1,90 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + 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) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_ALTERNATIVE_IPP) +#define BOOST_SPIRIT_ALTERNATIVE_IPP + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // alternative class implementation + // + /////////////////////////////////////////////////////////////////////////// + template <typename A, typename B> + inline alternative<A, B> + operator|(parser<A> const& a, parser<B> const& b) + { + return alternative<A, B>(a.derived(), b.derived()); + } + + template <typename A> + inline alternative<A, chlit<char> > + operator|(parser<A> const& a, char b) + { + return alternative<A, chlit<char> >(a.derived(), b); + } + + template <typename B> + inline alternative<chlit<char>, B> + operator|(char a, parser<B> const& b) + { + return alternative<chlit<char>, B>(a, b.derived()); + } + + template <typename A> + inline alternative<A, strlit<char const*> > + operator|(parser<A> const& a, char const* b) + { + return alternative<A, strlit<char const*> >(a.derived(), b); + } + + template <typename B> + inline alternative<strlit<char const*>, B> + operator|(char const* a, parser<B> const& b) + { + return alternative<strlit<char const*>, B>(a, b.derived()); + } + + template <typename A> + inline alternative<A, chlit<wchar_t> > + operator|(parser<A> const& a, wchar_t b) + { + return alternative<A, chlit<wchar_t> >(a.derived(), b); + } + + template <typename B> + inline alternative<chlit<wchar_t>, B> + operator|(wchar_t a, parser<B> const& b) + { + return alternative<chlit<wchar_t>, B>(a, b.derived()); + } + + template <typename A> + inline alternative<A, strlit<wchar_t const*> > + operator|(parser<A> const& a, wchar_t const* b) + { + return alternative<A, strlit<wchar_t const*> >(a.derived(), b); + } + + template <typename B> + inline alternative<strlit<wchar_t const*>, B> + operator|(wchar_t const* a, parser<B> const& b) + { + return alternative<strlit<wchar_t const*>, B>(a, b.derived()); + } + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#endif diff --git a/boost/spirit/home/classic/core/composite/impl/difference.ipp b/boost/spirit/home/classic/core/composite/impl/difference.ipp new file mode 100644 index 0000000000..f5df8c7528 --- /dev/null +++ b/boost/spirit/home/classic/core/composite/impl/difference.ipp @@ -0,0 +1,90 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + 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) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_DIFFERENCE_IPP) +#define BOOST_SPIRIT_DIFFERENCE_IPP + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // difference class implementation + // + /////////////////////////////////////////////////////////////////////////// + template <typename A, typename B> + inline difference<A, B> + operator-(parser<A> const& a, parser<B> const& b) + { + return difference<A, B>(a.derived(), b.derived()); + } + + template <typename A> + inline difference<A, chlit<char> > + operator-(parser<A> const& a, char b) + { + return difference<A, chlit<char> >(a.derived(), b); + } + + template <typename B> + inline difference<chlit<char>, B> + operator-(char a, parser<B> const& b) + { + return difference<chlit<char>, B>(a, b.derived()); + } + + template <typename A> + inline difference<A, strlit<char const*> > + operator-(parser<A> const& a, char const* b) + { + return difference<A, strlit<char const*> >(a.derived(), b); + } + + template <typename B> + inline difference<strlit<char const*>, B> + operator-(char const* a, parser<B> const& b) + { + return difference<strlit<char const*>, B>(a, b.derived()); + } + + template <typename A> + inline difference<A, chlit<wchar_t> > + operator-(parser<A> const& a, wchar_t b) + { + return difference<A, chlit<wchar_t> >(a.derived(), b); + } + + template <typename B> + inline difference<chlit<wchar_t>, B> + operator-(wchar_t a, parser<B> const& b) + { + return difference<chlit<wchar_t>, B>(a, b.derived()); + } + + template <typename A> + inline difference<A, strlit<wchar_t const*> > + operator-(parser<A> const& a, wchar_t const* b) + { + return difference<A, strlit<wchar_t const*> >(a.derived(), b); + } + + template <typename B> + inline difference<strlit<wchar_t const*>, B> + operator-(wchar_t const* a, parser<B> const& b) + { + return difference<strlit<wchar_t const*>, B>(a, b.derived()); + } + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#endif diff --git a/boost/spirit/home/classic/core/composite/impl/directives.ipp b/boost/spirit/home/classic/core/composite/impl/directives.ipp new file mode 100644 index 0000000000..b25b25fdc0 --- /dev/null +++ b/boost/spirit/home/classic/core/composite/impl/directives.ipp @@ -0,0 +1,374 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2001 Bruce Florman + Copyright (c) 2002 Raghavendra Satish + 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) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_DIRECTIVES_IPP) +#define BOOST_SPIRIT_DIRECTIVES_IPP + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/spirit/home/classic/core/scanner/skipper.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + template <typename BaseT> + struct no_skipper_iteration_policy; + + template <typename BaseT> + struct inhibit_case_iteration_policy; + + template <typename A, typename B> + struct alternative; + + template <typename A, typename B> + struct longest_alternative; + + template <typename A, typename B> + struct shortest_alternative; + + namespace impl + { + template <typename RT, typename ST, typename ScannerT, typename BaseT> + inline RT + contiguous_parser_parse( + ST const& s, + ScannerT const& scan, + skipper_iteration_policy<BaseT> const&) + { + typedef scanner_policies< + no_skipper_iteration_policy< + BOOST_DEDUCED_TYPENAME ScannerT::iteration_policy_t>, + BOOST_DEDUCED_TYPENAME ScannerT::match_policy_t, + BOOST_DEDUCED_TYPENAME ScannerT::action_policy_t + > policies_t; + + scan.skip(scan); + RT hit = s.parse(scan.change_policies(policies_t(scan))); + // We will not do a post skip!!! + return hit; + } + + template <typename RT, typename ST, typename ScannerT, typename BaseT> + inline RT + contiguous_parser_parse( + ST const& s, + ScannerT const& scan, + no_skipper_iteration_policy<BaseT> const&) + { + return s.parse(scan); + } + + template <typename RT, typename ST, typename ScannerT> + inline RT + contiguous_parser_parse( + ST const& s, + ScannerT const& scan, + iteration_policy const&) + { + return s.parse(scan); + } + + template < + typename RT, + typename ParserT, + typename ScannerT, + typename BaseT> + inline RT + implicit_lexeme_parse( + ParserT const& p, + ScannerT const& scan, + skipper_iteration_policy<BaseT> const&) + { + typedef scanner_policies< + no_skipper_iteration_policy< + BOOST_DEDUCED_TYPENAME ScannerT::iteration_policy_t>, + BOOST_DEDUCED_TYPENAME ScannerT::match_policy_t, + BOOST_DEDUCED_TYPENAME ScannerT::action_policy_t + > policies_t; + + scan.skip(scan); + RT hit = p.parse_main(scan.change_policies(policies_t(scan))); + // We will not do a post skip!!! + return hit; + } + + template < + typename RT, + typename ParserT, + typename ScannerT, + typename BaseT> + inline RT + implicit_lexeme_parse( + ParserT const& p, + ScannerT const& scan, + no_skipper_iteration_policy<BaseT> const&) + { + return p.parse_main(scan); + } + + template <typename RT, typename ParserT, typename ScannerT> + inline RT + implicit_lexeme_parse( + ParserT const& p, + ScannerT const& scan, + iteration_policy const&) + { + return p.parse_main(scan); + } + + template <typename RT, typename ST, typename ScannerT> + inline RT + inhibit_case_parser_parse( + ST const& s, + ScannerT const& scan, + iteration_policy const&) + { + typedef scanner_policies< + inhibit_case_iteration_policy< + BOOST_DEDUCED_TYPENAME ScannerT::iteration_policy_t>, + BOOST_DEDUCED_TYPENAME ScannerT::match_policy_t, + BOOST_DEDUCED_TYPENAME ScannerT::action_policy_t + > policies_t; + + return s.parse(scan.change_policies(policies_t(scan))); + } + + template <typename RT, typename ST, typename ScannerT, typename BaseT> + inline RT + inhibit_case_parser_parse( + ST const& s, + ScannerT const& scan, + inhibit_case_iteration_policy<BaseT> const&) + { + return s.parse(scan); + } + +#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + + /////////////////////////////////////////////////////////////////////// + // + // from spirit 1.1 (copyright (c) 2001 Bruce Florman) + // various workarounds to support longest and shortest directives + // + /////////////////////////////////////////////////////////////////////// + template <typename T> + struct is_alternative + { + // Determine at compile time (without partial specialization) + // whether a given type is an instance of the alternative<A,B> + + static T t(); + template <typename A, typename B> + static char test_(alternative<A, B> const&); // no implementation + static int test_(...); // no implementation + enum { r = sizeof(char) == sizeof(test_(t())) }; + typedef mpl::bool_<r> value; + }; + + template <typename T> struct select_to_longest; + + template <typename T> + struct to_longest_alternative + { + typedef typename select_to_longest<T>::result_t result_t; + typedef typename select_to_longest<T>::plain_t plain_t; + typedef typename select_to_longest<T>::choose_t choose_t; + static result_t convert(T const& a); + }; + + template <typename T> + struct to_longest_generic + { + typedef T const& result_t; + typedef T plain_t; + typedef mpl::false_ choose_t; + }; + + template <typename T> + inline T const& + to_longest_convert(T const& a, mpl::false_) + { return a; } + + template <typename T> + struct to_longest_recursive + { + typedef typename to_longest_alternative< + typename T::left_t>::plain_t a_t; + typedef typename to_longest_alternative< + typename T::right_t>::plain_t b_t; + + typedef longest_alternative<a_t, b_t> result_t; + + typedef result_t plain_t; + typedef mpl::true_ choose_t; + }; + + template <typename A, typename B> + inline typename to_longest_alternative<alternative<A, B> >::result_t + to_longest_convert(alternative<A, B> const& alt, mpl::true_) + { + typedef typename to_longest_alternative< + alternative<A, B> >::result_t result_t; + return result_t( + to_longest_alternative<A>::convert(alt.left()), + to_longest_alternative<B>::convert(alt.right())); + } + + template <typename T> + inline typename to_longest_alternative<T>::result_t + to_longest_alternative<T>::convert(T const& a) + { + return to_longest_convert( + a, to_longest_alternative<T>::choose_t()); + } + + template <typename T> + struct select_to_longest + { + typedef typename mpl::if_< + is_alternative<T> // IF + , to_longest_recursive<T> // THEN + , to_longest_generic<T> // ELSE + >::type type; + + typedef typename select_to_longest::type::result_t result_t; + typedef typename select_to_longest::type::plain_t plain_t; + typedef typename select_to_longest::type::choose_t choose_t; + }; + + template <typename T> struct select_to_shortest; + + template <typename T> + struct to_shortest_alternative + { + typedef typename select_to_shortest<T>::result_t result_t; + typedef typename select_to_shortest<T>::plain_t plain_t; + typedef typename select_to_shortest<T>::choose_t choose_t; + static result_t convert(T const& a); + }; + + template <typename T> + struct to_shortest_generic + { + typedef T const& result_t; + typedef T plain_t; + typedef mpl::false_ choose_t; + }; + + template <typename T> + inline T const& + to_shortest_convert(T const& a, mpl::false_) { return a; } + + template <typename T> + struct to_shortest_recursive + { + typedef typename to_shortest_alternative< + typename T::left_t>::plain_t a_t; + typedef typename to_shortest_alternative< + typename T::right_t>::plain_t b_t; + + typedef shortest_alternative<a_t, b_t> result_t; + + typedef result_t plain_t; + typedef mpl::true_ choose_t; + }; + + template <typename A, typename B> + inline typename to_shortest_alternative<alternative<A, B> >::result_t + to_shortest_convert(alternative<A, B> const& alt, mpl::true_) + { + typedef typename to_shortest_alternative< + alternative<A, B> >::result_t result_t; + return result_t( + to_shortest_alternative<A>::convert(alt.left()), + to_shortest_alternative<B>::convert(alt.right())); + } + + template <typename T> + inline typename to_shortest_alternative<T>::result_t + to_shortest_alternative<T>::convert(T const& a) + { + return to_shortest_convert( + a, to_shortest_alternative<T>::choose_t()); + } + + template <typename T> + struct select_to_shortest + { + typedef typename mpl::if_< + is_alternative<T> // IF + , to_shortest_recursive<T> // THEN + , to_shortest_generic<T> // ELSE + >::type type; + + typedef typename select_to_shortest::type::result_t result_t; + typedef typename select_to_shortest::type::plain_t plain_t; + typedef typename select_to_shortest::type::choose_t choose_t; + }; +#else + template <typename T> + struct to_longest_alternative + { + typedef T result_t; + static result_t const& + convert(T const& a) // Special (end) case + { return a; } + }; + + template <typename A, typename B> + struct to_longest_alternative<alternative<A, B> > + { + typedef typename to_longest_alternative<A>::result_t a_t; + typedef typename to_longest_alternative<B>::result_t b_t; + typedef longest_alternative<a_t, b_t> result_t; + + static result_t + convert(alternative<A, B> const& alt) // Recursive case + { + return result_t( + to_longest_alternative<A>::convert(alt.left()), + to_longest_alternative<B>::convert(alt.right())); + } + }; + + template <typename T> + struct to_shortest_alternative + { + typedef T result_t; + static result_t const& + convert(T const& a) // Special (end) case + { return a; } + }; + + template <typename A, typename B> + struct to_shortest_alternative<alternative<A, B> > + { + typedef typename to_shortest_alternative<A>::result_t a_t; + typedef typename to_shortest_alternative<B>::result_t b_t; + typedef shortest_alternative<a_t, b_t> result_t; + + static result_t + convert(alternative<A, B> const& alt) // Recursive case + { + return result_t( + to_shortest_alternative<A>::convert(alt.left()), + to_shortest_alternative<B>::convert(alt.right())); + } + }; +#endif + } + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#endif + diff --git a/boost/spirit/home/classic/core/composite/impl/exclusive_or.ipp b/boost/spirit/home/classic/core/composite/impl/exclusive_or.ipp new file mode 100644 index 0000000000..34831a7e9f --- /dev/null +++ b/boost/spirit/home/classic/core/composite/impl/exclusive_or.ipp @@ -0,0 +1,90 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + 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) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_EXCLUSIVE_OR_IPP) +#define BOOST_SPIRIT_EXCLUSIVE_OR_IPP + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // exclusive_or class implementation + // + /////////////////////////////////////////////////////////////////////////// + template <typename A, typename B> + inline exclusive_or<A, B> + operator^(parser<A> const& a, parser<B> const& b) + { + return exclusive_or<A, B>(a.derived(), b.derived()); + } + + template <typename A> + inline exclusive_or<A, chlit<char> > + operator^(parser<A> const& a, char b) + { + return exclusive_or<A, chlit<char> >(a.derived(), b); + } + + template <typename B> + inline exclusive_or<chlit<char>, B> + operator^(char a, parser<B> const& b) + { + return exclusive_or<chlit<char>, B>(a, b.derived()); + } + + template <typename A> + inline exclusive_or<A, strlit<char const*> > + operator^(parser<A> const& a, char const* b) + { + return exclusive_or<A, strlit<char const*> >(a.derived(), b); + } + + template <typename B> + inline exclusive_or<strlit<char const*>, B> + operator^(char const* a, parser<B> const& b) + { + return exclusive_or<strlit<char const*>, B>(a, b.derived()); + } + + template <typename A> + inline exclusive_or<A, chlit<wchar_t> > + operator^(parser<A> const& a, wchar_t b) + { + return exclusive_or<A, chlit<wchar_t> >(a.derived(), b); + } + + template <typename B> + inline exclusive_or<chlit<wchar_t>, B> + operator^(wchar_t a, parser<B> const& b) + { + return exclusive_or<chlit<wchar_t>, B>(a, b.derived()); + } + + template <typename A> + inline exclusive_or<A, strlit<wchar_t const*> > + operator^(parser<A> const& a, wchar_t const* b) + { + return exclusive_or<A, strlit<wchar_t const*> >(a.derived(), b); + } + + template <typename B> + inline exclusive_or<strlit<wchar_t const*>, B> + operator^(wchar_t const* a, parser<B> const& b) + { + return exclusive_or<strlit<wchar_t const*>, B>(a, b.derived()); + } + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#endif diff --git a/boost/spirit/home/classic/core/composite/impl/intersection.ipp b/boost/spirit/home/classic/core/composite/impl/intersection.ipp new file mode 100644 index 0000000000..2810586cd7 --- /dev/null +++ b/boost/spirit/home/classic/core/composite/impl/intersection.ipp @@ -0,0 +1,90 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + 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) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_INTERSECTION_IPP) +#define BOOST_SPIRIT_INTERSECTION_IPP + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // intersection class implementation + // + /////////////////////////////////////////////////////////////////////////// + template <typename A, typename B> + inline intersection<A, B> + operator&(parser<A> const& a, parser<B> const& b) + { + return intersection<A, B>(a.derived(), b.derived()); + } + + template <typename A> + inline intersection<A, chlit<char> > + operator&(parser<A> const& a, char b) + { + return intersection<A, chlit<char> >(a.derived(), b); + } + + template <typename B> + inline intersection<chlit<char>, B> + operator&(char a, parser<B> const& b) + { + return intersection<chlit<char>, B>(a, b.derived()); + } + + template <typename A> + inline intersection<A, strlit<char const*> > + operator&(parser<A> const& a, char const* b) + { + return intersection<A, strlit<char const*> >(a.derived(), b); + } + + template <typename B> + inline intersection<strlit<char const*>, B> + operator&(char const* a, parser<B> const& b) + { + return intersection<strlit<char const*>, B>(a, b.derived()); + } + + template <typename A> + inline intersection<A, chlit<wchar_t> > + operator&(parser<A> const& a, wchar_t b) + { + return intersection<A, chlit<wchar_t> >(a.derived(), b); + } + + template <typename B> + inline intersection<chlit<wchar_t>, B> + operator&(wchar_t a, parser<B> const& b) + { + return intersection<chlit<wchar_t>, B>(a, b.derived()); + } + + template <typename A> + inline intersection<A, strlit<wchar_t const*> > + operator&(parser<A> const& a, wchar_t const* b) + { + return intersection<A, strlit<wchar_t const*> >(a.derived(), b); + } + + template <typename B> + inline intersection<strlit<wchar_t const*>, B> + operator&(wchar_t const* a, parser<B> const& b) + { + return intersection<strlit<wchar_t const*>, B>(a, b.derived()); + } + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#endif diff --git a/boost/spirit/home/classic/core/composite/impl/kleene_star.ipp b/boost/spirit/home/classic/core/composite/impl/kleene_star.ipp new file mode 100644 index 0000000000..8c4f5135c0 --- /dev/null +++ b/boost/spirit/home/classic/core/composite/impl/kleene_star.ipp @@ -0,0 +1,34 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + 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) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_KLEENE_STAR_IPP) +#define BOOST_SPIRIT_KLEENE_STAR_IPP + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // kleene_star class implementation + // + /////////////////////////////////////////////////////////////////////////// + template <typename S> + inline kleene_star<S> + operator*(parser<S> const& a) + { + return kleene_star<S>(a.derived()); + } + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#endif diff --git a/boost/spirit/home/classic/core/composite/impl/list.ipp b/boost/spirit/home/classic/core/composite/impl/list.ipp new file mode 100644 index 0000000000..cd7965adfd --- /dev/null +++ b/boost/spirit/home/classic/core/composite/impl/list.ipp @@ -0,0 +1,93 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + 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) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_LIST_IPP) +#define BOOST_SPIRIT_LIST_IPP + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // operator% is defined as: + // a % b ---> a >> *(b >> a) + // + /////////////////////////////////////////////////////////////////////////// + template <typename A, typename B> + inline sequence<A, kleene_star<sequence<B, A> > > + operator%(parser<A> const& a, parser<B> const& b) + { + return a.derived() >> *(b.derived() >> a.derived()); + } + + template <typename A> + inline sequence<A, kleene_star<sequence<chlit<char>, A> > > + operator%(parser<A> const& a, char b) + { + return a.derived() >> *(b >> a.derived()); + } + + template <typename B> + inline sequence<chlit<char>, kleene_star<sequence<B, chlit<char> > > > + operator%(char a, parser<B> const& b) + { + return a >> *(b.derived() >> a); + } + + template <typename A> + inline sequence<A, kleene_star<sequence<strlit<char const*>, A> > > + operator%(parser<A> const& a, char const* b) + { + return a.derived() >> *(b >> a.derived()); + } + + template <typename B> + inline sequence<strlit<char const*>, + kleene_star<sequence<B, strlit<char const*> > > > + operator%(char const* a, parser<B> const& b) + { + return a >> *(b.derived() >> a); + } + + template <typename A> + inline sequence<A, kleene_star<sequence<chlit<wchar_t>, A> > > + operator%(parser<A> const& a, wchar_t b) + { + return a.derived() >> *(b >> a.derived()); + } + + template <typename B> + inline sequence<chlit<wchar_t>, kleene_star<sequence<B, chlit<wchar_t> > > > + operator%(wchar_t a, parser<B> const& b) + { + return a >> *(b.derived() >> a); + } + + template <typename A> + inline sequence<A, kleene_star<sequence<strlit<wchar_t const*>, A> > > + operator%(parser<A> const& a, wchar_t const* b) + { + return a.derived() >> *(b >> a.derived()); + } + + template <typename B> + inline sequence<strlit<wchar_t const*>, + kleene_star<sequence<B, strlit<wchar_t const*> > > > + operator%(wchar_t const* a, parser<B> const& b) + { + return a >> *(b.derived() >> a); + } + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#endif diff --git a/boost/spirit/home/classic/core/composite/impl/optional.ipp b/boost/spirit/home/classic/core/composite/impl/optional.ipp new file mode 100644 index 0000000000..629eac8336 --- /dev/null +++ b/boost/spirit/home/classic/core/composite/impl/optional.ipp @@ -0,0 +1,34 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + 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) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_OPTIONAL_IPP) +#define BOOST_SPIRIT_OPTIONAL_IPP + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // optional class implementation + // + /////////////////////////////////////////////////////////////////////////// + template <typename S> + optional<S> + operator!(parser<S> const& a) + { + return optional<S>(a.derived()); + } + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#endif diff --git a/boost/spirit/home/classic/core/composite/impl/positive.ipp b/boost/spirit/home/classic/core/composite/impl/positive.ipp new file mode 100644 index 0000000000..9698e69e55 --- /dev/null +++ b/boost/spirit/home/classic/core/composite/impl/positive.ipp @@ -0,0 +1,34 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + 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) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_POSITIVE_IPP) +#define BOOST_SPIRIT_POSITIVE_IPP + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // positive class implementation + // + /////////////////////////////////////////////////////////////////////////// + template <typename S> + inline positive<S> + operator+(parser<S> const& a) + { + return positive<S>(a.derived()); + } + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#endif diff --git a/boost/spirit/home/classic/core/composite/impl/sequence.ipp b/boost/spirit/home/classic/core/composite/impl/sequence.ipp new file mode 100644 index 0000000000..283d420bc3 --- /dev/null +++ b/boost/spirit/home/classic/core/composite/impl/sequence.ipp @@ -0,0 +1,90 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + 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) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_SEQUENCE_IPP) +#define BOOST_SPIRIT_SEQUENCE_IPP + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // sequence class implementation + // + /////////////////////////////////////////////////////////////////////////// + template <typename A, typename B> + inline sequence<A, B> + operator>>(parser<A> const& a, parser<B> const& b) + { + return sequence<A, B>(a.derived(), b.derived()); + } + + template <typename A> + inline sequence<A, chlit<char> > + operator>>(parser<A> const& a, char b) + { + return sequence<A, chlit<char> >(a.derived(), b); + } + + template <typename B> + inline sequence<chlit<char>, B> + operator>>(char a, parser<B> const& b) + { + return sequence<chlit<char>, B>(a, b.derived()); + } + + template <typename A> + inline sequence<A, strlit<char const*> > + operator>>(parser<A> const& a, char const* b) + { + return sequence<A, strlit<char const*> >(a.derived(), b); + } + + template <typename B> + inline sequence<strlit<char const*>, B> + operator>>(char const* a, parser<B> const& b) + { + return sequence<strlit<char const*>, B>(a, b.derived()); + } + + template <typename A> + inline sequence<A, chlit<wchar_t> > + operator>>(parser<A> const& a, wchar_t b) + { + return sequence<A, chlit<wchar_t> >(a.derived(), b); + } + + template <typename B> + inline sequence<chlit<wchar_t>, B> + operator>>(wchar_t a, parser<B> const& b) + { + return sequence<chlit<wchar_t>, B>(a, b.derived()); + } + + template <typename A> + inline sequence<A, strlit<wchar_t const*> > + operator>>(parser<A> const& a, wchar_t const* b) + { + return sequence<A, strlit<wchar_t const*> >(a.derived(), b); + } + + template <typename B> + inline sequence<strlit<wchar_t const*>, B> + operator>>(wchar_t const* a, parser<B> const& b) + { + return sequence<strlit<wchar_t const*>, B>(a, b.derived()); + } + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#endif diff --git a/boost/spirit/home/classic/core/composite/impl/sequential_and.ipp b/boost/spirit/home/classic/core/composite/impl/sequential_and.ipp new file mode 100644 index 0000000000..9f577a4f55 --- /dev/null +++ b/boost/spirit/home/classic/core/composite/impl/sequential_and.ipp @@ -0,0 +1,90 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + 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) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_SEQUENTIAL_AND_IPP) +#define BOOST_SPIRIT_SEQUENTIAL_AND_IPP + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // sequential-and operators implementation + // + /////////////////////////////////////////////////////////////////////////// + template <typename A, typename B> + inline sequence<A, B> + operator&&(parser<A> const& a, parser<B> const& b) + { + return sequence<A, B>(a.derived(), b.derived()); + } + + template <typename A> + inline sequence<A, chlit<char> > + operator&&(parser<A> const& a, char b) + { + return sequence<A, chlit<char> >(a.derived(), b); + } + + template <typename B> + inline sequence<chlit<char>, B> + operator&&(char a, parser<B> const& b) + { + return sequence<chlit<char>, B>(a, b.derived()); + } + + template <typename A> + inline sequence<A, strlit<char const*> > + operator&&(parser<A> const& a, char const* b) + { + return sequence<A, strlit<char const*> >(a.derived(), b); + } + + template <typename B> + inline sequence<strlit<char const*>, B> + operator&&(char const* a, parser<B> const& b) + { + return sequence<strlit<char const*>, B>(a, b.derived()); + } + + template <typename A> + inline sequence<A, chlit<wchar_t> > + operator&&(parser<A> const& a, wchar_t b) + { + return sequence<A, chlit<wchar_t> >(a.derived(), b); + } + + template <typename B> + inline sequence<chlit<wchar_t>, B> + operator&&(wchar_t a, parser<B> const& b) + { + return sequence<chlit<wchar_t>, B>(a, b.derived()); + } + + template <typename A> + inline sequence<A, strlit<wchar_t const*> > + operator&&(parser<A> const& a, wchar_t const* b) + { + return sequence<A, strlit<wchar_t const*> >(a.derived(), b); + } + + template <typename B> + inline sequence<strlit<wchar_t const*>, B> + operator&&(wchar_t const* a, parser<B> const& b) + { + return sequence<strlit<wchar_t const*>, B>(a, b.derived()); + } + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#endif diff --git a/boost/spirit/home/classic/core/composite/impl/sequential_or.ipp b/boost/spirit/home/classic/core/composite/impl/sequential_or.ipp new file mode 100644 index 0000000000..521faf61ec --- /dev/null +++ b/boost/spirit/home/classic/core/composite/impl/sequential_or.ipp @@ -0,0 +1,90 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + 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) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_SEQUENTIAL_OR_IPP) +#define BOOST_SPIRIT_SEQUENTIAL_OR_IPP + +namespace boost { namespace spirit { + + BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // sequential-or class implementation + // + /////////////////////////////////////////////////////////////////////////// + template <typename A, typename B> + inline sequential_or<A, B> + operator||(parser<A> const& a, parser<B> const& b) + { + return sequential_or<A, B>(a.derived(), b.derived()); + } + + template <typename A> + inline sequential_or<A, chlit<char> > + operator||(parser<A> const& a, char b) + { + return sequential_or<A, chlit<char> >(a.derived(), b); + } + + template <typename B> + inline sequential_or<chlit<char>, B> + operator||(char a, parser<B> const& b) + { + return sequential_or<chlit<char>, B>(a, b.derived()); + } + + template <typename A> + inline sequential_or<A, strlit<char const*> > + operator||(parser<A> const& a, char const* b) + { + return sequential_or<A, strlit<char const*> >(a.derived(), b); + } + + template <typename B> + inline sequential_or<strlit<char const*>, B> + operator||(char const* a, parser<B> const& b) + { + return sequential_or<strlit<char const*>, B>(a, b.derived()); + } + + template <typename A> + inline sequential_or<A, chlit<wchar_t> > + operator||(parser<A> const& a, wchar_t b) + { + return sequential_or<A, chlit<wchar_t> >(a.derived(), b); + } + + template <typename B> + inline sequential_or<chlit<wchar_t>, B> + operator||(wchar_t a, parser<B> const& b) + { + return sequential_or<chlit<wchar_t>, B>(a, b.derived()); + } + + template <typename A> + inline sequential_or<A, strlit<wchar_t const*> > + operator||(parser<A> const& a, wchar_t const* b) + { + return sequential_or<A, strlit<wchar_t const*> >(a.derived(), b); + } + + template <typename B> + inline sequential_or<strlit<wchar_t const*>, B> + operator||(wchar_t const* a, parser<B> const& b) + { + return sequential_or<strlit<wchar_t const*>, B>(a, b.derived()); + } + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#endif diff --git a/boost/spirit/home/classic/core/composite/intersection.hpp b/boost/spirit/home/classic/core/composite/intersection.hpp new file mode 100644 index 0000000000..867c20f330 --- /dev/null +++ b/boost/spirit/home/classic/core/composite/intersection.hpp @@ -0,0 +1,142 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_INTERSECTION_HPP) +#define BOOST_SPIRIT_INTERSECTION_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/core/primitives/primitives.hpp> +#include <boost/spirit/home/classic/core/composite/composite.hpp> +#include <boost/spirit/home/classic/meta/as_parser.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // intersection class + // + // Handles expressions of the form: + // + // a & b + // + // where a and b are parsers. The expression returns a composite + // parser that matches a and b. One (not both) of the operands may + // be a literal char, wchar_t or a primitive string char const*, + // wchar_t const*. + // + // The expression is short circuit evaluated. b is never touched + // when a is returns a no-match. + // + /////////////////////////////////////////////////////////////////////////// + struct intersection_parser_gen; + + template <typename A, typename B> + struct intersection + : public binary<A, B, parser<intersection<A, B> > > + { + typedef intersection<A, B> self_t; + typedef binary_parser_category parser_category_t; + typedef intersection_parser_gen parser_generator_t; + typedef binary<A, B, parser<self_t> > base_t; + + intersection(A const& a, B const& b) + : base_t(a, b) {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename parser_result<self_t, ScannerT>::type result_t; + typedef typename ScannerT::iterator_t iterator_t; + iterator_t save = scan.first; + if (result_t hl = this->left().parse(scan)) + { + ScannerT bscan(scan.first, scan.first, scan); + scan.first = save; + result_t hr = this->right().parse(bscan); + if (hl.length() == hr.length()) + return hl; + } + + return scan.no_match(); + } + }; + + struct intersection_parser_gen + { + template <typename A, typename B> + struct result + { + typedef + intersection< + typename as_parser<A>::type + , typename as_parser<B>::type + > + type; + }; + + template <typename A, typename B> + static intersection< + typename as_parser<A>::type + , typename as_parser<B>::type + > + generate(A const& a, B const& b) + { + return intersection<BOOST_DEDUCED_TYPENAME as_parser<A>::type, + BOOST_DEDUCED_TYPENAME as_parser<B>::type> + (as_parser<A>::convert(a), as_parser<B>::convert(b)); + } + }; + + template <typename A, typename B> + intersection<A, B> + operator&(parser<A> const& a, parser<B> const& b); + + template <typename A> + intersection<A, chlit<char> > + operator&(parser<A> const& a, char b); + + template <typename B> + intersection<chlit<char>, B> + operator&(char a, parser<B> const& b); + + template <typename A> + intersection<A, strlit<char const*> > + operator&(parser<A> const& a, char const* b); + + template <typename B> + intersection<strlit<char const*>, B> + operator&(char const* a, parser<B> const& b); + + template <typename A> + intersection<A, chlit<wchar_t> > + operator&(parser<A> const& a, wchar_t b); + + template <typename B> + intersection<chlit<wchar_t>, B> + operator&(wchar_t a, parser<B> const& b); + + template <typename A> + intersection<A, strlit<wchar_t const*> > + operator&(parser<A> const& a, wchar_t const* b); + + template <typename B> + intersection<strlit<wchar_t const*>, B> + operator&(wchar_t const* a, parser<B> const& b); + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + +#include <boost/spirit/home/classic/core/composite/impl/intersection.ipp> diff --git a/boost/spirit/home/classic/core/composite/kleene_star.hpp b/boost/spirit/home/classic/core/composite/kleene_star.hpp new file mode 100644 index 0000000000..9b6c73a008 --- /dev/null +++ b/boost/spirit/home/classic/core/composite/kleene_star.hpp @@ -0,0 +1,109 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_KLEENE_STAR_HPP) +#define BOOST_SPIRIT_KLEENE_STAR_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/core/primitives/primitives.hpp> +#include <boost/spirit/home/classic/core/composite/composite.hpp> +#include <boost/spirit/home/classic/meta/as_parser.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // kleene_star class + // + // Handles expressions of the form: + // + // *a + // + // where a is a parser. The expression returns a composite + // parser that matches its subject zero (0) or more times. + // + /////////////////////////////////////////////////////////////////////////// + struct kleene_star_parser_gen; + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(push) +#pragma warning(disable:4512) //assignment operator could not be generated +#endif + + template <typename S> + struct kleene_star + : public unary<S, parser<kleene_star<S> > > + { + typedef kleene_star<S> self_t; + typedef unary_parser_category parser_category_t; + typedef kleene_star_parser_gen parser_generator_t; + typedef unary<S, parser<self_t> > base_t; + + kleene_star(S const& a) + : base_t(a) {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename parser_result<self_t, ScannerT>::type result_t; + typedef typename ScannerT::iterator_t iterator_t; + result_t hit = scan.empty_match(); + + for (;;) + { + iterator_t save = scan.first; + if (result_t next = this->subject().parse(scan)) + { + scan.concat_match(hit, next); + } + else + { + scan.first = save; + return hit; + } + } + } + }; + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(pop) +#endif + + struct kleene_star_parser_gen + { + template <typename S> + struct result + { + typedef kleene_star<S> type; + }; + + template <typename S> + static kleene_star<S> + generate(parser<S> const& a) + { + return kleene_star<S>(a.derived()); + } + }; + + ////////////////////////////////// + template <typename S> + kleene_star<S> + operator*(parser<S> const& a); + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + +#include <boost/spirit/home/classic/core/composite/impl/kleene_star.ipp> diff --git a/boost/spirit/home/classic/core/composite/list.hpp b/boost/spirit/home/classic/core/composite/list.hpp new file mode 100644 index 0000000000..cdb879e14a --- /dev/null +++ b/boost/spirit/home/classic/core/composite/list.hpp @@ -0,0 +1,73 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_LIST_HPP) +#define BOOST_SPIRIT_LIST_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/core/primitives/primitives.hpp> +#include <boost/spirit/home/classic/core/composite/composite.hpp> +#include <boost/spirit/home/classic/meta/as_parser.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // operator% is defined as: + // a % b ---> a >> *(b >> a) + // + /////////////////////////////////////////////////////////////////////////// + template <typename A, typename B> + sequence<A, kleene_star<sequence<B, A> > > + operator%(parser<A> const& a, parser<B> const& b); + + template <typename A> + sequence<A, kleene_star<sequence<chlit<char>, A> > > + operator%(parser<A> const& a, char b); + + template <typename B> + sequence<chlit<char>, kleene_star<sequence<B, chlit<char> > > > + operator%(char a, parser<B> const& b); + + template <typename A> + sequence<A, kleene_star<sequence<strlit<char const*>, A> > > + operator%(parser<A> const& a, char const* b); + + template <typename B> + sequence<strlit<char const*>, + kleene_star<sequence<B, strlit<char const*> > > > + operator%(char const* a, parser<B> const& b); + + template <typename A> + sequence<A, kleene_star<sequence<chlit<wchar_t>, A> > > + operator%(parser<A> const& a, wchar_t b); + + template <typename B> + sequence<chlit<wchar_t>, kleene_star<sequence<B, chlit<wchar_t> > > > + operator%(wchar_t a, parser<B> const& b); + + template <typename A> + sequence<A, kleene_star<sequence<strlit<wchar_t const*>, A> > > + operator%(parser<A> const& a, wchar_t const* b); + + template <typename B> + sequence<strlit<wchar_t const*>, + kleene_star<sequence<B, strlit<wchar_t const*> > > > + operator%(wchar_t const* a, parser<B> const& b); + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + +#include <boost/spirit/home/classic/core/composite/impl/list.ipp> diff --git a/boost/spirit/home/classic/core/composite/no_actions.hpp b/boost/spirit/home/classic/core/composite/no_actions.hpp new file mode 100644 index 0000000000..638a29778f --- /dev/null +++ b/boost/spirit/home/classic/core/composite/no_actions.hpp @@ -0,0 +1,165 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2003 Vaclav Vesely + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_NO_ACTIONS_HPP) +#define BOOST_SPIRIT_NO_ACTIONS_HPP + +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/core/composite/composite.hpp> +#include <boost/spirit/home/classic/core/non_terminal/rule.hpp> + +namespace boost { +namespace spirit { +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +//----------------------------------------------------------------------------- +// no_actions_action_policy + +template<typename BaseT = action_policy> +struct no_actions_action_policy: + public BaseT +{ + typedef BaseT base_t; + + no_actions_action_policy(): + BaseT() + {} + + template<typename PolicyT> + no_actions_action_policy(PolicyT const& other): + BaseT(other) + {} + + template<typename ActorT, typename AttrT, typename IteratorT> + void + do_action( + ActorT const& actor, + AttrT& val, + IteratorT const& first, + IteratorT const& last) const + {} +}; + +//----------------------------------------------------------------------------- +// no_actions_scanner + + +namespace detail +{ + template <typename ActionPolicy> + struct compute_no_actions_action_policy + { + typedef no_actions_action_policy<ActionPolicy> type; + }; + + template <typename ActionPolicy> + struct compute_no_actions_action_policy<no_actions_action_policy<ActionPolicy> > + { + typedef no_actions_action_policy<ActionPolicy> type; + }; +} + +template<typename ScannerT = scanner<> > +struct no_actions_scanner +{ + typedef scanner_policies< + typename ScannerT::iteration_policy_t, + typename ScannerT::match_policy_t, + typename detail::compute_no_actions_action_policy<typename ScannerT::action_policy_t>::type + > policies_t; + + typedef typename + rebind_scanner_policies<ScannerT, policies_t>::type type; +}; + +#if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1 + +template<typename ScannerT = scanner<> > +struct no_actions_scanner_list +{ + typedef + scanner_list< + ScannerT, + typename no_actions_scanner<ScannerT>::type + > + type; +}; + +#endif // BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1 + +//----------------------------------------------------------------------------- +// no_actions_parser + +struct no_actions_parser_gen; + +template<typename ParserT> +struct no_actions_parser: + public unary<ParserT, parser<no_actions_parser<ParserT> > > +{ + typedef no_actions_parser<ParserT> self_t; + typedef unary_parser_category parser_category_t; + typedef no_actions_parser_gen parser_generator_t; + typedef unary<ParserT, parser<self_t> > base_t; + + template<typename ScannerT> + struct result + { + typedef typename parser_result<ParserT, ScannerT>::type type; + }; + + no_actions_parser(ParserT const& p) + : base_t(p) + {} + + template<typename ScannerT> + typename result<ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename no_actions_scanner<ScannerT>::policies_t policies_t; + + return this->subject().parse(scan.change_policies(policies_t(scan))); + } +}; + +//----------------------------------------------------------------------------- +// no_actions_parser_gen + +struct no_actions_parser_gen +{ + template<typename ParserT> + struct result + { + typedef no_actions_parser<ParserT> type; + }; + + template<typename ParserT> + static no_actions_parser<ParserT> + generate(parser<ParserT> const& subject) + { + return no_actions_parser<ParserT>(subject.derived()); + } + + template<typename ParserT> + no_actions_parser<ParserT> + operator[](parser<ParserT> const& subject) const + { + return no_actions_parser<ParserT>(subject.derived()); + } +}; + +//----------------------------------------------------------------------------- +// no_actions_d + +const no_actions_parser_gen no_actions_d = no_actions_parser_gen(); + +//----------------------------------------------------------------------------- +BOOST_SPIRIT_CLASSIC_NAMESPACE_END +} // namespace spirit +} // namespace boost + +#endif // !defined(BOOST_SPIRIT_NO_ACTIONS_HPP) diff --git a/boost/spirit/home/classic/core/composite/operators.hpp b/boost/spirit/home/classic/core/composite/operators.hpp new file mode 100644 index 0000000000..5732ef9ae7 --- /dev/null +++ b/boost/spirit/home/classic/core/composite/operators.hpp @@ -0,0 +1,25 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_OPERATORS_HPP) +#define BOOST_SPIRIT_OPERATORS_HPP + +#include <boost/spirit/home/classic/core/composite/sequence.hpp> +#include <boost/spirit/home/classic/core/composite/sequential_and.hpp> +#include <boost/spirit/home/classic/core/composite/sequential_or.hpp> +#include <boost/spirit/home/classic/core/composite/alternative.hpp> +#include <boost/spirit/home/classic/core/composite/difference.hpp> +#include <boost/spirit/home/classic/core/composite/intersection.hpp> +#include <boost/spirit/home/classic/core/composite/exclusive_or.hpp> +#include <boost/spirit/home/classic/core/composite/kleene_star.hpp> +#include <boost/spirit/home/classic/core/composite/positive.hpp> +#include <boost/spirit/home/classic/core/composite/optional.hpp> +#include <boost/spirit/home/classic/core/composite/list.hpp> + +#endif diff --git a/boost/spirit/home/classic/core/composite/optional.hpp b/boost/spirit/home/classic/core/composite/optional.hpp new file mode 100644 index 0000000000..69e49f9a3a --- /dev/null +++ b/boost/spirit/home/classic/core/composite/optional.hpp @@ -0,0 +1,94 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_OPTIONAL_HPP) +#define BOOST_SPIRIT_OPTIONAL_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/core/primitives/primitives.hpp> +#include <boost/spirit/home/classic/core/composite/composite.hpp> +#include <boost/spirit/home/classic/meta/as_parser.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // optional class + // + // Handles expressions of the form: + // + // !a + // + // where a is a parser. The expression returns a composite + // parser that matches its subject zero (0) or one (1) time. + // + /////////////////////////////////////////////////////////////////////////// + struct optional_parser_gen; + + template <typename S> + struct optional + : public unary<S, parser<optional<S> > > + { + typedef optional<S> self_t; + typedef unary_parser_category parser_category_t; + typedef optional_parser_gen parser_generator_t; + typedef unary<S, parser<self_t> > base_t; + + optional(S const& a) + : base_t(a) {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename parser_result<self_t, ScannerT>::type result_t; + typedef typename ScannerT::iterator_t iterator_t; + iterator_t save = scan.first; + if (result_t r = this->subject().parse(scan)) + { + return r; + } + else + { + scan.first = save; + return scan.empty_match(); + } + } + }; + + struct optional_parser_gen + { + template <typename S> + struct result + { + typedef optional<S> type; + }; + + template <typename S> + static optional<S> + generate(parser<S> const& a) + { + return optional<S>(a.derived()); + } + }; + + template <typename S> + optional<S> + operator!(parser<S> const& a); + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + +#include <boost/spirit/home/classic/core/composite/impl/optional.ipp> diff --git a/boost/spirit/home/classic/core/composite/positive.hpp b/boost/spirit/home/classic/core/composite/positive.hpp new file mode 100644 index 0000000000..7b494b45ca --- /dev/null +++ b/boost/spirit/home/classic/core/composite/positive.hpp @@ -0,0 +1,112 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_POSITIVE_HPP) +#define BOOST_SPIRIT_POSITIVE_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/core/primitives/primitives.hpp> +#include <boost/spirit/home/classic/core/composite/composite.hpp> +#include <boost/spirit/home/classic/meta/as_parser.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // positive class + // + // Handles expressions of the form: + // + // +a + // + // where a is a parser. The expression returns a composite + // parser that matches its subject one (1) or more times. + // + /////////////////////////////////////////////////////////////////////////// + struct positive_parser_gen; + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(push) +#pragma warning(disable:4512) //assignment operator could not be generated +#endif + + template <typename S> + struct positive + : public unary<S, parser<positive<S> > > + { + typedef positive<S> self_t; + typedef unary_parser_category parser_category_t; + typedef positive_parser_gen parser_generator_t; + typedef unary<S, parser<self_t> > base_t; + + positive(S const& a) + : base_t(a) {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename parser_result<self_t, ScannerT>::type result_t; + typedef typename ScannerT::iterator_t iterator_t; + result_t hit = this->subject().parse(scan); + + if (hit) + { + for (;;) + { + iterator_t save = scan.first; + if (result_t next = this->subject().parse(scan)) + { + scan.concat_match(hit, next); + } + else + { + scan.first = save; + break; + } + } + } + return hit; + } + }; + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(pop) +#endif + + struct positive_parser_gen + { + template <typename S> + struct result + { + typedef positive<S> type; + }; + + template <typename S> + static positive<S> + generate(parser<S> const& a) + { + return positive<S>(a.derived()); + } + }; + + template <typename S> + inline positive<S> + operator+(parser<S> const& a); + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + +#include <boost/spirit/home/classic/core/composite/impl/positive.ipp> diff --git a/boost/spirit/home/classic/core/composite/sequence.hpp b/boost/spirit/home/classic/core/composite/sequence.hpp new file mode 100644 index 0000000000..3ccd9ea7a8 --- /dev/null +++ b/boost/spirit/home/classic/core/composite/sequence.hpp @@ -0,0 +1,142 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_SEQUENCE_HPP) +#define BOOST_SPIRIT_SEQUENCE_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/core/primitives/primitives.hpp> +#include <boost/spirit/home/classic/core/composite/composite.hpp> +#include <boost/spirit/home/classic/meta/as_parser.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // sequence class + // + // Handles expressions of the form: + // + // a >> b + // + // where a and b are parsers. The expression returns a composite + // parser that matches a and b in sequence. One (not both) of the + // operands may be a literal char, wchar_t or a primitive string + // char const*, wchar_t const*. + // + ////////////////////////////////////////////////////////////////////////// + struct sequence_parser_gen; + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(push) +#pragma warning(disable:4512) //assignment operator could not be generated +#endif + + template <typename A, typename B> + struct sequence : public binary<A, B, parser<sequence<A, B> > > + { + typedef sequence<A, B> self_t; + typedef binary_parser_category parser_category_t; + typedef sequence_parser_gen parser_generator_t; + typedef binary<A, B, parser<self_t> > base_t; + + sequence(A const& a, B const& b) + : base_t(a, b) {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename parser_result<self_t, ScannerT>::type result_t; + if (result_t ma = this->left().parse(scan)) + if (result_t mb = this->right().parse(scan)) + { + scan.concat_match(ma, mb); + return ma; + } + return scan.no_match(); + } + }; + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(pop) +#endif + + struct sequence_parser_gen + { + template <typename A, typename B> + struct result + { + typedef + sequence< + typename as_parser<A>::type + , typename as_parser<B>::type + > + type; + }; + + template <typename A, typename B> + static sequence< + typename as_parser<A>::type + , typename as_parser<B>::type + > + generate(A const& a, B const& b) + { + return sequence<BOOST_DEDUCED_TYPENAME as_parser<A>::type, + BOOST_DEDUCED_TYPENAME as_parser<B>::type> + (as_parser<A>::convert(a), as_parser<B>::convert(b)); + } + }; + + template <typename A, typename B> + sequence<A, B> + operator>>(parser<A> const& a, parser<B> const& b); + + template <typename A> + sequence<A, chlit<char> > + operator>>(parser<A> const& a, char b); + + template <typename B> + sequence<chlit<char>, B> + operator>>(char a, parser<B> const& b); + + template <typename A> + sequence<A, strlit<char const*> > + operator>>(parser<A> const& a, char const* b); + + template <typename B> + sequence<strlit<char const*>, B> + operator>>(char const* a, parser<B> const& b); + + template <typename A> + sequence<A, chlit<wchar_t> > + operator>>(parser<A> const& a, wchar_t b); + + template <typename B> + sequence<chlit<wchar_t>, B> + operator>>(wchar_t a, parser<B> const& b); + + template <typename A> + sequence<A, strlit<wchar_t const*> > + operator>>(parser<A> const& a, wchar_t const* b); + + template <typename B> + sequence<strlit<wchar_t const*>, B> + operator>>(wchar_t const* a, parser<B> const& b); + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + +#include <boost/spirit/home/classic/core/composite/impl/sequence.ipp> diff --git a/boost/spirit/home/classic/core/composite/sequential_and.hpp b/boost/spirit/home/classic/core/composite/sequential_and.hpp new file mode 100644 index 0000000000..da11f8729a --- /dev/null +++ b/boost/spirit/home/classic/core/composite/sequential_and.hpp @@ -0,0 +1,76 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_SEQUENTIAL_AND_HPP) +#define BOOST_SPIRIT_SEQUENTIAL_AND_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/core/primitives/primitives.hpp> +#include <boost/spirit/home/classic/core/composite/composite.hpp> +#include <boost/spirit/home/classic/meta/as_parser.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // sequential-and operators + // + // Handles expressions of the form: + // + // a && b + // + // Same as a >> b. + // + /////////////////////////////////////////////////////////////////////////// + template <typename A, typename B> + sequence<A, B> + operator&&(parser<A> const& a, parser<B> const& b); + + template <typename A> + sequence<A, chlit<char> > + operator&&(parser<A> const& a, char b); + + template <typename B> + sequence<chlit<char>, B> + operator&&(char a, parser<B> const& b); + + template <typename A> + sequence<A, strlit<char const*> > + operator&&(parser<A> const& a, char const* b); + + template <typename B> + sequence<strlit<char const*>, B> + operator&&(char const* a, parser<B> const& b); + + template <typename A> + sequence<A, chlit<wchar_t> > + operator&&(parser<A> const& a, wchar_t b); + + template <typename B> + sequence<chlit<wchar_t>, B> + operator&&(wchar_t a, parser<B> const& b); + + template <typename A> + sequence<A, strlit<wchar_t const*> > + operator&&(parser<A> const& a, wchar_t const* b); + + template <typename B> + sequence<strlit<wchar_t const*>, B> + operator&&(wchar_t const* a, parser<B> const& b); + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + +#include <boost/spirit/home/classic/core/composite/impl/sequential_and.ipp> diff --git a/boost/spirit/home/classic/core/composite/sequential_or.hpp b/boost/spirit/home/classic/core/composite/sequential_or.hpp new file mode 100644 index 0000000000..b276f6c9c3 --- /dev/null +++ b/boost/spirit/home/classic/core/composite/sequential_or.hpp @@ -0,0 +1,154 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_SEQUENTIAL_OR_HPP) +#define BOOST_SPIRIT_SEQUENTIAL_OR_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/core/primitives/primitives.hpp> +#include <boost/spirit/home/classic/core/composite/composite.hpp> +#include <boost/spirit/home/classic/meta/as_parser.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // sequential-or class + // + // Handles expressions of the form: + // + // a || b + // + // Equivalent to + // + // a | b | a >> b; + // + // where a and b are parsers. The expression returns a composite + // parser that matches matches a or b in sequence. One (not both) of + // the operands may be a literal char, wchar_t or a primitive string + // char const*, wchar_t const*. + // + /////////////////////////////////////////////////////////////////////////// + struct sequential_or_parser_gen; + + template <typename A, typename B> + struct sequential_or : public binary<A, B, parser<sequential_or<A, B> > > + { + typedef sequential_or<A, B> self_t; + typedef binary_parser_category parser_category_t; + typedef sequential_or_parser_gen parser_generator_t; + typedef binary<A, B, parser<self_t> > base_t; + + sequential_or(A const& a, B const& b) + : base_t(a, b) {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename parser_result<self_t, ScannerT>::type result_t; + typedef typename ScannerT::iterator_t iterator_t; + { // scope for save + iterator_t save = scan.first; + if (result_t ma = this->left().parse(scan)) + { + save = scan.first; + if (result_t mb = this->right().parse(scan)) + { + // matched a b + scan.concat_match(ma, mb); + return ma; + } + else + { + // matched a + scan.first = save; + return ma; + } + } + scan.first = save; + } + + // matched b + return this->right().parse(scan); + } + }; + + struct sequential_or_parser_gen + { + template <typename A, typename B> + struct result + { + typedef + sequential_or< + typename as_parser<A>::type + , typename as_parser<B>::type + > + type; + }; + + template <typename A, typename B> + static sequential_or< + typename as_parser<A>::type + , typename as_parser<B>::type + > + generate(A const& a, B const& b) + { + return sequential_or<BOOST_DEDUCED_TYPENAME as_parser<A>::type, + BOOST_DEDUCED_TYPENAME as_parser<B>::type> + (as_parser<A>::convert(a), as_parser<B>::convert(b)); + } + }; + + template <typename A, typename B> + sequential_or<A, B> + operator||(parser<A> const& a, parser<B> const& b); + + template <typename A> + sequential_or<A, chlit<char> > + operator||(parser<A> const& a, char b); + + template <typename B> + sequential_or<chlit<char>, B> + operator||(char a, parser<B> const& b); + + template <typename A> + sequential_or<A, strlit<char const*> > + operator||(parser<A> const& a, char const* b); + + template <typename B> + sequential_or<strlit<char const*>, B> + operator||(char const* a, parser<B> const& b); + + template <typename A> + sequential_or<A, chlit<wchar_t> > + operator||(parser<A> const& a, wchar_t b); + + template <typename B> + sequential_or<chlit<wchar_t>, B> + operator||(wchar_t a, parser<B> const& b); + + template <typename A> + sequential_or<A, strlit<wchar_t const*> > + operator||(parser<A> const& a, wchar_t const* b); + + template <typename B> + sequential_or<strlit<wchar_t const*>, B> + operator||(wchar_t const* a, parser<B> const& b); + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + +#include <boost/spirit/home/classic/core/composite/impl/sequential_or.ipp> diff --git a/boost/spirit/home/classic/core/config.hpp b/boost/spirit/home/classic/core/config.hpp new file mode 100644 index 0000000000..57eca7f037 --- /dev/null +++ b/boost/spirit/home/classic/core/config.hpp @@ -0,0 +1,62 @@ +/*============================================================================= + Copyright (c) 2001-2003 Joel de Guzman + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_CONFIG_HPP) +#define BOOST_SPIRIT_CONFIG_HPP + +#include <boost/config.hpp> + +/////////////////////////////////////////////////////////////////////////////// +// +// Compiler check: +// +// Historically, Spirit supported a lot of compilers, including (to some +// extent) poorly conforming compilers such as VC6. Spirit v1.6.x will be +// the last release that will support older poorly conforming compilers. +// Starting from Spirit v1.8.0, ill conforming compilers will not be +// supported. If you are still using one of these older compilers, you can +// still use Spirit v1.6.x. +// +// The reason why Spirit v1.6.x worked on old non-conforming compilers is +// that the authors laboriously took the trouble of searching for +// workarounds to make these compilers happy. The process takes a lot of +// time and energy, especially when one encounters the dreaded ICE or +// "Internal Compiler Error". Sometimes searching for a single workaround +// takes days or even weeks. Sometimes, there are no known workarounds. This +// stifles progress a lot. And, as the library gets more progressive and +// takes on more advanced C++ techniques, the difficulty is escalated to +// even new heights. +// +// Spirit v1.6.x will still be supported. Maintenance and bug fixes will +// still be applied. There will still be active development for the back- +// porting of new features introduced in Spirit v1.8.0 (and Spirit 1.9.0) +// to lesser able compilers; hopefully, fueled by contributions from the +// community. For instance, there is already a working AST tree back-port +// for VC6 and VC7 by Peder Holt. +// +// If you got here somehow, your compiler is known to be poorly conforming +// WRT ANSI/ISO C++ standard. Library implementers get a bad reputation when +// someone attempts to compile the code on a non-conforming compiler. She'll +// be confronted with tons of compiler errors when she tries to compile the +// library. Such errors will somehow make less informed users conclude that +// the code is poorly written. It's better for the user to see a message +// "sorry, this code has not been ported to your compiler yet", than to see +// pages and pages of compiler error messages. +// +///////////////////////////////////////////////////////////////////////////////// +#if (defined(BOOST_MSVC) && (BOOST_MSVC < 1310)) \ + || (defined(__BORLANDC__) && (__BORLANDC__ <= 0x570)) \ + || (defined(__GNUC__) && (__GNUC__ < 3)) \ + || (defined(__GNUC__) && (__GNUC__ == 3) && (__GNUC_MINOR__ < 1)) +# error "Compiler not supported. See note in <boost/spirit/core/config.hpp>" +#else +// Pass... Compiler supported. +#endif + +#endif + + diff --git a/boost/spirit/home/classic/core/impl/match.ipp b/boost/spirit/home/classic/core/impl/match.ipp new file mode 100644 index 0000000000..0319dcf4e3 --- /dev/null +++ b/boost/spirit/home/classic/core/impl/match.ipp @@ -0,0 +1,113 @@ +/*============================================================================= + Copyright (c) 1998-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) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_MATCH_IPP) +#define BOOST_SPIRIT_MATCH_IPP +#include <algorithm> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + template <typename T> + inline match<T>::match() + : len(-1), val() {} + + template <typename T> + inline match<T>::match(std::size_t length_) + : len(length_), val() {} + + template <typename T> + inline match<T>::match(std::size_t length_, ctor_param_t val_) + : len(length_), val(val_) {} + + template <typename T> + inline bool + match<T>::operator!() const + { + return len < 0; + } + + template <typename T> + inline std::ptrdiff_t + match<T>::length() const + { + return len; + } + + template <typename T> + inline bool + match<T>::has_valid_attribute() const + { + return val.is_initialized(); + } + + template <typename T> + inline typename match<T>::return_t + match<T>::value() const + { + BOOST_SPIRIT_ASSERT(val.is_initialized()); + return *val; + } + + template <typename T> + inline void + match<T>::swap(match& other) + { + std::swap(len, other.len); + std::swap(val, other.val); + } + + inline match<nil_t>::match() + : len(-1) {} + + inline match<nil_t>::match(std::size_t length_) + : len(length_) {} + + inline match<nil_t>::match(std::size_t length_, nil_t) + : len(length_) {} + + inline bool + match<nil_t>::operator!() const + { + return len < 0; + } + + inline bool + match<nil_t>::has_valid_attribute() const + { + return false; + } + + inline std::ptrdiff_t + match<nil_t>::length() const + { + return len; + } + + inline nil_t + match<nil_t>::value() const + { + return nil_t(); + } + + inline void + match<nil_t>::value(nil_t) {} + + inline void + match<nil_t>::swap(match<nil_t>& other) + { + std::swap(len, other.len); + } + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#endif + diff --git a/boost/spirit/home/classic/core/impl/match_attr_traits.ipp b/boost/spirit/home/classic/core/impl/match_attr_traits.ipp new file mode 100644 index 0000000000..24d9a43791 --- /dev/null +++ b/boost/spirit/home/classic/core/impl/match_attr_traits.ipp @@ -0,0 +1,102 @@ +/*============================================================================= + Copyright (c) 1998-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) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_MATCH_ATTR_TRAITS_IPP) +#define BOOST_SPIRIT_MATCH_ATTR_TRAITS_IPP + +#include <boost/optional.hpp> +#include <boost/mpl/bool.hpp> +#include <boost/mpl/or.hpp> +#include <boost/type_traits/is_convertible.hpp> +#include <boost/type_traits/is_same.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +namespace impl +{ + template <typename T> + struct match_attr_traits + { + typedef typename + boost::optional<T>::reference_const_type + const_reference; + + // case where src *IS* convertible to T (dest) + template <typename T2> + static void + convert(boost::optional<T>& dest, T2 const& src, mpl::true_) + { + dest.reset(src); + } + + // case where src *IS NOT* convertible to T (dest) + template <typename T2> + static void + convert(boost::optional<T>& dest, T2 const& /*src*/, mpl::false_) + { + dest.reset(); + } + + static void + convert(boost::optional<T>& dest, nil_t/*src*/) + { + dest.reset(); + } + + template <typename T2> + static void + convert(boost::optional<T>& dest, T2 const& src) + { + convert(dest, src, is_convertible<T2, T>()); + } + + template <typename OtherMatchT> + static void + copy(boost::optional<T>& dest, OtherMatchT const& src) + { + if (src.has_valid_attribute()) + convert(dest, src.value()); + } + + template <typename OtherMatchT> + static void + assign(boost::optional<T>& dest, OtherMatchT const& src) + { + if (src.has_valid_attribute()) + convert(dest, src.value()); + else + dest.reset(); + } + + // T is not reference + template <typename ValueT> + static void + set_value(boost::optional<T>& dest, ValueT const& val, mpl::false_) + { + dest.reset(val); + } + + // T is a reference + template <typename ValueT> + static void + set_value(boost::optional<T>& dest, ValueT const& val, mpl::true_) + { + dest.get() = val; + } + }; + +} + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit::impl + +#endif + diff --git a/boost/spirit/home/classic/core/impl/parser.ipp b/boost/spirit/home/classic/core/impl/parser.ipp new file mode 100644 index 0000000000..d5abe692fa --- /dev/null +++ b/boost/spirit/home/classic/core/impl/parser.ipp @@ -0,0 +1,55 @@ +/*============================================================================= + Copyright (c) 1998-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) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_PARSER_IPP) +#define BOOST_SPIRIT_PARSER_IPP + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // Generic parse function implementation + // + /////////////////////////////////////////////////////////////////////////// + template <typename IteratorT, typename DerivedT> + inline parse_info<IteratorT> + parse( + IteratorT const& first_ + , IteratorT const& last + , parser<DerivedT> const& p) + { + IteratorT first = first_; + scanner<IteratorT, scanner_policies<> > scan(first, last); + match<nil_t> hit = p.derived().parse(scan); + return parse_info<IteratorT>( + first, hit, hit && (first == last), hit.length()); + } + + /////////////////////////////////////////////////////////////////////////// + // + // Parse function for null terminated strings implementation + // + /////////////////////////////////////////////////////////////////////////// + template <typename CharT, typename DerivedT> + inline parse_info<CharT const*> + parse(CharT const* str, parser<DerivedT> const& p) + { + CharT const* last = str; + while (*last) + last++; + return parse(str, last, p); + } + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#endif + diff --git a/boost/spirit/home/classic/core/match.hpp b/boost/spirit/home/classic/core/match.hpp new file mode 100644 index 0000000000..6f1822ece3 --- /dev/null +++ b/boost/spirit/home/classic/core/match.hpp @@ -0,0 +1,185 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_MATCH_HPP) +#define BOOST_SPIRIT_MATCH_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/config.hpp> +#include <boost/spirit/home/classic/core/nil.hpp> +#include <boost/call_traits.hpp> +#include <boost/optional.hpp> +#include <boost/spirit/home/classic/core/assert.hpp> +#include <boost/spirit/home/classic/core/safe_bool.hpp> +#include <boost/spirit/home/classic/core/impl/match_attr_traits.ipp> +#include <boost/type_traits/add_const.hpp> +#include <boost/type_traits/is_reference.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // match class + // + // The match holds the result of a parser. A match object evaluates + // to true when a successful match is found, otherwise false. The + // length of the match is the number of characters (or tokens) that + // is successfully matched. This can be queried through its length() + // member function. A negative value means that the match is + // unsucessful. + // + // Each parser may have an associated attribute. This attribute is + // also returned back to the client on a successful parse through + // the match object. The match's value() member function returns the + // match's attribute. + // + // A match attribute is valid: + // + // * on a successful match + // * when its value is set through the value(val) member function + // * if it is assigned or copied from a compatible match object + // (e.g. match<double> from match<int>) with a valid attribute. + // + // The match attribute is undefined: + // + // * on an unsuccessful match + // * when an attempt to copy or assign from another match object + // with an incompatible attribute type (e.g. match<std::string> + // from match<int>). + // + // The member function has_valid_attribute() can be queried to know if + // it is safe to get the match's attribute. The attribute may be set + // through the member function value(v) where v is the new attribute + // value. + // + /////////////////////////////////////////////////////////////////////////// + template <typename T = nil_t> + class match : public safe_bool<match<T> > + { + + public: + + typedef typename boost::optional<T> optional_type; + typedef typename optional_type::argument_type ctor_param_t; + typedef typename optional_type::reference_const_type return_t; + typedef T attr_t; + + match(); + explicit match(std::size_t length); + match(std::size_t length, ctor_param_t val); + + bool operator!() const; + std::ptrdiff_t length() const; + bool has_valid_attribute() const; + return_t value() const; + void swap(match& other); + + template <typename T2> + match(match<T2> const& other) + : len(other.length()), val() + { + impl::match_attr_traits<T>::copy(val, other); + } + + template <typename T2> + match& + operator=(match<T2> const& other) + { + impl::match_attr_traits<T>::assign(val, other); + len = other.length(); + return *this; + } + + template <typename MatchT> + void + concat(MatchT const& other) + { + BOOST_SPIRIT_ASSERT(*this && other); + len += other.length(); + } + + template <typename ValueT> + void + value(ValueT const& val_) + { + impl::match_attr_traits<T>::set_value(val, val_, is_reference<T>()); + } + + bool operator_bool() const + { + return len >= 0; + } + + private: + + std::ptrdiff_t len; + optional_type val; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // match class specialization for nil_t values + // + /////////////////////////////////////////////////////////////////////////// + template <> + class match<nil_t> : public safe_bool<match<nil_t> > + { + public: + + typedef nil_t attr_t; + typedef nil_t return_t; + + match(); + explicit match(std::size_t length); + match(std::size_t length, nil_t); + + bool operator!() const; + bool has_valid_attribute() const; + std::ptrdiff_t length() const; + nil_t value() const; + void value(nil_t); + void swap(match& other); + + template <typename T> + match(match<T> const& other) + : len(other.length()) {} + + template <typename T> + match<>& + operator=(match<T> const& other) + { + len = other.length(); + return *this; + } + + template <typename T> + void + concat(match<T> const& other) + { + BOOST_SPIRIT_ASSERT(*this && other); + len += other.length(); + } + + bool operator_bool() const + { + return len >= 0; + } + + private: + + std::ptrdiff_t len; + }; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif +#include <boost/spirit/home/classic/core/impl/match.ipp> + diff --git a/boost/spirit/home/classic/core/nil.hpp b/boost/spirit/home/classic/core/nil.hpp new file mode 100644 index 0000000000..c94c064d6b --- /dev/null +++ b/boost/spirit/home/classic/core/nil.hpp @@ -0,0 +1,25 @@ +/*============================================================================= + Copyright (c) 2001-2003 Joel de Guzman + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_NIL_HPP) +#define BOOST_SPIRIT_NIL_HPP + +#include <boost/spirit/home/classic/namespace.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + struct nil_t {}; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} + +#endif + + diff --git a/boost/spirit/home/classic/core/non_terminal/grammar.hpp b/boost/spirit/home/classic/core/non_terminal/grammar.hpp new file mode 100644 index 0000000000..ae7b2658f3 --- /dev/null +++ b/boost/spirit/home/classic/core/non_terminal/grammar.hpp @@ -0,0 +1,85 @@ +/*============================================================================= + Copyright (c) 2001-2003 Joel de Guzman + Copyright (c) 2002-2003 Martin Wille + Copyright (c) 2003 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_GRAMMAR_HPP) +#define BOOST_SPIRIT_GRAMMAR_HPP + +/////////////////////////////////////////////////////////////////////////////// +#if defined(BOOST_SPIRIT_THREADSAFE) && defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE) +#undef BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE +#endif + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/core/non_terminal/parser_context.hpp> +#include <boost/spirit/home/classic/core/non_terminal/impl/grammar.ipp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// +// grammar class +// +/////////////////////////////////////////////////////////////////////////////// +template <typename DerivedT, typename ContextT = parser_context<> > +struct grammar + : public parser<DerivedT> + , public ContextT::base_t + , public context_aux<ContextT, DerivedT> + BOOST_SPIRIT_GRAMMAR_ID +{ + typedef grammar<DerivedT, ContextT> self_t; + typedef DerivedT const& embed_t; + typedef typename ContextT::context_linker_t context_t; + typedef typename context_t::attr_t attr_t; + + template <typename ScannerT> + struct result + { + typedef typename match_result<ScannerT, attr_t>::type type; + }; + + grammar() {} + ~grammar() { impl::grammar_destruct(this); } + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse_main(ScannerT const& scan) const + { return impl::grammar_parser_parse<0>(this, scan); } + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename parser_result<self_t, ScannerT>::type result_t; + typedef parser_scanner_linker<ScannerT> scanner_t; + BOOST_SPIRIT_CONTEXT_PARSE(scan, *this, scanner_t, context_t, result_t) + } + + template <int N> + impl::entry_grammar<DerivedT, N, ContextT> + use_parser() const + { return impl::entry_grammar<DerivedT, N, ContextT>( this->derived()); } + + BOOST_SPIRIT_GRAMMAR_STATE +}; + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#undef BOOST_SPIRIT_GRAMMAR_ID +#undef BOOST_SPIRIT_GRAMMAR_ACCESS +#undef BOOST_SPIRIT_GRAMMAR_STATE +#endif + diff --git a/boost/spirit/home/classic/core/non_terminal/impl/grammar.ipp b/boost/spirit/home/classic/core/non_terminal/impl/grammar.ipp new file mode 100644 index 0000000000..3b25b3d2e3 --- /dev/null +++ b/boost/spirit/home/classic/core/non_terminal/impl/grammar.ipp @@ -0,0 +1,407 @@ +/*============================================================================= + Copyright (c) 2001-2003 Joel de Guzman + Copyright (c) 2002-2003 Martin Wille + Copyright (c) 2003 Hartmut Kaiser + 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) +=============================================================================*/ +#if !defined BOOST_SPIRIT_GRAMMAR_IPP +#define BOOST_SPIRIT_GRAMMAR_IPP + +#if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE) +#include <boost/spirit/home/classic/core/non_terminal/impl/object_with_id.ipp> +#include <algorithm> +#include <functional> +#include <memory> // for std::auto_ptr +#include <boost/weak_ptr.hpp> +#endif + +#ifdef BOOST_SPIRIT_THREADSAFE +#include <boost/spirit/home/classic/core/non_terminal/impl/static.hpp> +#include <boost/thread/tss.hpp> +#include <boost/thread/mutex.hpp> +#endif + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +template <typename DerivedT, typename ContextT> +struct grammar; + +#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300) + +BOOST_SPIRIT_DEPENDENT_TEMPLATE_WRAPPER(grammar_definition_wrapper, definition); + +////////////////////////////////// +template <typename GrammarT, typename ScannerT> +struct grammar_definition +{ + typedef typename impl::grammar_definition_wrapper<GrammarT> + ::template result_<ScannerT>::param_t type; +}; + +#else + +////////////////////////////////// +template <typename GrammarT, typename ScannerT> +struct grammar_definition +{ + typedef typename GrammarT::template definition<ScannerT> type; +}; + +#endif + + namespace impl + { + +#if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE) + struct grammar_tag {}; + + ////////////////////////////////// + template <typename GrammarT> + struct grammar_helper_base + { + virtual int undefine(GrammarT *) = 0; + virtual ~grammar_helper_base() {} + }; + + ////////////////////////////////// + template <typename GrammarT> + struct grammar_helper_list + { + typedef GrammarT grammar_t; + typedef grammar_helper_base<GrammarT> helper_t; + typedef std::vector<helper_t*> vector_t; + + grammar_helper_list() {} + grammar_helper_list(grammar_helper_list const& /*x*/) + { // Does _not_ copy the helpers member ! + } + + grammar_helper_list& operator=(grammar_helper_list const& x) + { // Does _not_ copy the helpers member ! + return *this; + } + + void push_back(helper_t *helper) + { helpers.push_back(helper); } + + void pop_back() + { helpers.pop_back(); } + + typename vector_t::size_type + size() const + { return helpers.size(); } + + typename vector_t::reverse_iterator + rbegin() + { return helpers.rbegin(); } + + typename vector_t::reverse_iterator + rend() + { return helpers.rend(); } + +#ifdef BOOST_SPIRIT_THREADSAFE + boost::mutex & mutex() + { return m; } +#endif + + private: + + vector_t helpers; +#ifdef BOOST_SPIRIT_THREADSAFE + boost::mutex m; +#endif + }; + + ////////////////////////////////// + struct grammartract_helper_list; + +#if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE) \ + && (!defined(__GNUC__) || (__GNUC__ > 2)) + + struct grammartract_helper_list + { + template<typename GrammarT> + static grammar_helper_list<GrammarT>& + do_(GrammarT const* g) + { + return g->helpers; + } + }; + +#endif + + ////////////////////////////////// + template <typename GrammarT, typename DerivedT, typename ScannerT> + struct grammar_helper : private grammar_helper_base<GrammarT> + { + typedef GrammarT grammar_t; + typedef ScannerT scanner_t; + typedef DerivedT derived_t; + typedef typename grammar_definition<DerivedT, ScannerT>::type definition_t; + + typedef grammar_helper<grammar_t, derived_t, scanner_t> helper_t; + typedef boost::shared_ptr<helper_t> helper_ptr_t; + typedef boost::weak_ptr<helper_t> helper_weak_ptr_t; + + grammar_helper* + this_() { return this; } + + grammar_helper(helper_weak_ptr_t& p) + : definitions_cnt(0) + , self(this_()) + { p = self; } + + definition_t& + define(grammar_t const* target_grammar) + { + grammar_helper_list<GrammarT> &helpers = +#if !defined(__GNUC__) || (__GNUC__ > 2) + grammartract_helper_list::do_(target_grammar); +#else + target_grammar->helpers; +#endif + typename grammar_t::object_id id = target_grammar->get_object_id(); + + if (definitions.size()<=id) + definitions.resize(id*3/2+1); + if (definitions[id]!=0) + return *definitions[id]; + + std::auto_ptr<definition_t> + result(new definition_t(target_grammar->derived())); + +#ifdef BOOST_SPIRIT_THREADSAFE + boost::mutex::scoped_lock lock(helpers.mutex()); +#endif + helpers.push_back(this); + + ++definitions_cnt; + definitions[id] = result.get(); + return *(result.release()); + } + + int + undefine(grammar_t* target_grammar) + { + typename grammar_t::object_id id = target_grammar->get_object_id(); + + if (definitions.size()<=id) + return 0; + delete definitions[id]; + definitions[id] = 0; + if (--definitions_cnt==0) + self.reset(); + return 0; + } + + private: + + std::vector<definition_t*> definitions; + unsigned long definitions_cnt; + helper_ptr_t self; + }; + +#endif /* defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE) */ + +#ifdef BOOST_SPIRIT_THREADSAFE + class get_definition_static_data_tag + { + template<typename DerivedT, typename ContextT, typename ScannerT> + friend typename DerivedT::template definition<ScannerT> & + get_definition(grammar<DerivedT, ContextT> const* self); + + get_definition_static_data_tag() {} + }; +#endif + + template<typename DerivedT, typename ContextT, typename ScannerT> + inline typename DerivedT::template definition<ScannerT> & + get_definition(grammar<DerivedT, ContextT> const* self) + { +#if defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE) + + typedef typename DerivedT::template definition<ScannerT> definition_t; + static definition_t def(self->derived()); + return def; +#else + typedef grammar<DerivedT, ContextT> self_t; + typedef impl::grammar_helper<self_t, DerivedT, ScannerT> helper_t; + typedef typename helper_t::helper_weak_ptr_t ptr_t; + +# ifdef BOOST_SPIRIT_THREADSAFE + boost::thread_specific_ptr<ptr_t> & tld_helper + = static_<boost::thread_specific_ptr<ptr_t>, + get_definition_static_data_tag>(get_definition_static_data_tag()); + + if (!tld_helper.get()) + tld_helper.reset(new ptr_t); + ptr_t &helper = *tld_helper; +# else + static ptr_t helper; +# endif + if (helper.expired()) + new helper_t(helper); + return helper.lock()->define(self); +#endif + } + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + template <int N> + struct call_helper { + + template <typename RT, typename DefinitionT, typename ScannerT> + static void + do_ (RT &result, DefinitionT &def, ScannerT const &scan) + { + result = def.template get_start_parser<N>()->parse(scan); + } + }; +#else + // The grammar_def stuff isn't supported for compilers, which do not + // support partial template specialization + template <int N> struct call_helper; +#endif + + template <> + struct call_helper<0> { + + template <typename RT, typename DefinitionT, typename ScannerT> + static void + do_ (RT &result, DefinitionT &def, ScannerT const &scan) + { + result = def.start().parse(scan); + } + }; + + ////////////////////////////////// + template<int N, typename DerivedT, typename ContextT, typename ScannerT> + inline typename parser_result<grammar<DerivedT, ContextT>, ScannerT>::type + grammar_parser_parse( + grammar<DerivedT, ContextT> const* self, + ScannerT const &scan) + { + typedef + typename parser_result<grammar<DerivedT, ContextT>, ScannerT>::type + result_t; + typedef typename DerivedT::template definition<ScannerT> definition_t; + + result_t result; + definition_t &def = get_definition<DerivedT, ContextT, ScannerT>(self); + + call_helper<N>::do_(result, def, scan); + return result; + } + + ////////////////////////////////// + template<typename GrammarT> + inline void + grammar_destruct(GrammarT* self) + { +#if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE) + typedef impl::grammar_helper_base<GrammarT> helper_base_t; + typedef grammar_helper_list<GrammarT> helper_list_t; + typedef typename helper_list_t::vector_t::reverse_iterator iterator_t; + + helper_list_t& helpers = +# if !defined(__GNUC__) || (__GNUC__ > 2) + grammartract_helper_list::do_(self); +# else + self->helpers; +# endif + +# if (defined(BOOST_MSVC) && (BOOST_MSVC < 1300)) \ + || defined(BOOST_INTEL_CXX_VERSION) + for (iterator_t i = helpers.rbegin(); i != helpers.rend(); ++i) + (*i)->undefine(self); +# else + std::for_each(helpers.rbegin(), helpers.rend(), + std::bind2nd(std::mem_fun(&helper_base_t::undefine), self)); +# endif + +#else + (void)self; +#endif + } + + /////////////////////////////////////////////////////////////////////////// + // + // entry_grammar class + // + /////////////////////////////////////////////////////////////////////////// + template <typename DerivedT, int N, typename ContextT> + class entry_grammar + : public parser<entry_grammar<DerivedT, N, ContextT> > + { + + public: + typedef entry_grammar<DerivedT, N, ContextT> self_t; + typedef self_t embed_t; + typedef typename ContextT::context_linker_t context_t; + typedef typename context_t::attr_t attr_t; + + template <typename ScannerT> + struct result + { + typedef typename match_result<ScannerT, attr_t>::type type; + }; + + entry_grammar(DerivedT const &p) : target_grammar(p) {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse_main(ScannerT const& scan) const + { return impl::grammar_parser_parse<N>(&target_grammar, scan); } + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename parser_result<self_t, ScannerT>::type result_t; + typedef parser_scanner_linker<ScannerT> scanner_t; + BOOST_SPIRIT_CONTEXT_PARSE(scan, target_grammar, scanner_t, + context_t, result_t) + } + + private: + DerivedT const &target_grammar; + }; + + } // namespace impl + +/////////////////////////////////////// +#if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE) +#define BOOST_SPIRIT_GRAMMAR_ID , public impl::object_with_id<impl::grammar_tag> +#else +#define BOOST_SPIRIT_GRAMMAR_ID +#endif + +/////////////////////////////////////// +#if !defined(__GNUC__) || (__GNUC__ > 2) +#define BOOST_SPIRIT_GRAMMAR_ACCESS private: +#else +#define BOOST_SPIRIT_GRAMMAR_ACCESS +#endif + +/////////////////////////////////////// +#if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE) +#define BOOST_SPIRIT_GRAMMAR_STATE \ + BOOST_SPIRIT_GRAMMAR_ACCESS \ + friend struct impl::grammartract_helper_list; \ + mutable impl::grammar_helper_list<self_t> helpers; +#else +#define BOOST_SPIRIT_GRAMMAR_STATE +#endif + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#endif diff --git a/boost/spirit/home/classic/core/non_terminal/impl/object_with_id.ipp b/boost/spirit/home/classic/core/non_terminal/impl/object_with_id.ipp new file mode 100644 index 0000000000..822180a977 --- /dev/null +++ b/boost/spirit/home/classic/core/non_terminal/impl/object_with_id.ipp @@ -0,0 +1,191 @@ +/*============================================================================= + Copyright (c) 2002-2003 Joel de Guzman + Copyright (c) 2002-2003 Martin Wille + 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) +=============================================================================*/ +#if !defined BOOST_SPIRIT_OBJECT_WITH_ID_IPP +#define BOOST_SPIRIT_OBJECT_WITH_ID_IPP + +#include <vector> +#include <boost/shared_ptr.hpp> + +#ifdef BOOST_SPIRIT_THREADSAFE +#include <boost/thread/mutex.hpp> +#include <boost/thread/once.hpp> +#endif + +#include <boost/spirit/home/classic/namespace.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + namespace impl { + + ////////////////////////////////// + template <typename IdT = std::size_t> + struct object_with_id_base_supply + { + typedef IdT object_id; + typedef std::vector<object_id> id_vector; + + object_with_id_base_supply() : max_id(object_id()) {} + +#ifdef BOOST_SPIRIT_THREADSAFE + boost::mutex mutex; +#endif + object_id max_id; + id_vector free_ids; + + object_id acquire(); + void release(object_id); + }; + + ////////////////////////////////// + template <typename TagT, typename IdT = std::size_t> + struct object_with_id_base + { + typedef TagT tag_t; + typedef IdT object_id; + + protected: + + object_id acquire_object_id(); + void release_object_id(object_id); + + private: +#ifdef BOOST_SPIRIT_THREADSAFE + static boost::mutex &mutex_instance(); + static void mutex_init(); +#endif + + boost::shared_ptr<object_with_id_base_supply<IdT> > id_supply; + }; + + ////////////////////////////////// + template<class TagT, typename IdT = std::size_t> + struct object_with_id : private object_with_id_base<TagT, IdT> + { + typedef object_with_id<TagT, IdT> self_t; + typedef object_with_id_base<TagT, IdT> base_t; + typedef IdT object_id; + + object_with_id() : id(base_t::acquire_object_id()) {} + object_with_id(self_t const &other) + : base_t(other) + , id(base_t::acquire_object_id()) + {} // don't copy id + self_t &operator = (self_t const &other) + { // don't assign id + base_t::operator=(other); + return *this; + } + ~object_with_id() { base_t::release_object_id(id); } + object_id get_object_id() const { return id; } + + private: + + object_id const id; + }; + + ////////////////////////////////// + template <typename IdT> + inline IdT + object_with_id_base_supply<IdT>::acquire() + { +#ifdef BOOST_SPIRIT_THREADSAFE + boost::mutex::scoped_lock lock(mutex); +#endif + if (free_ids.size()) + { + object_id id = *free_ids.rbegin(); + free_ids.pop_back(); + return id; + } + else + { + if (free_ids.capacity()<=max_id) + free_ids.reserve(max_id*3/2+1); + return ++max_id; + } + } + + ////////////////////////////////// + template <typename IdT> + inline void + object_with_id_base_supply<IdT>::release(IdT id) + { +#ifdef BOOST_SPIRIT_THREADSAFE + boost::mutex::scoped_lock lock(mutex); +#endif + if (max_id == id) + max_id--; + else + free_ids.push_back(id); // doesn't throw + } + + ////////////////////////////////// + template <typename TagT, typename IdT> + inline IdT + object_with_id_base<TagT, IdT>::acquire_object_id() + { + { +#ifdef BOOST_SPIRIT_THREADSAFE + static boost::once_flag been_here = BOOST_ONCE_INIT; + boost::call_once(been_here, mutex_init); + boost::mutex &mutex = mutex_instance(); + boost::mutex::scoped_lock lock(mutex); +#endif + static boost::shared_ptr<object_with_id_base_supply<IdT> > + static_supply; + + if (!static_supply.get()) + static_supply.reset(new object_with_id_base_supply<IdT>()); + id_supply = static_supply; + } + + return id_supply->acquire(); + } + + ////////////////////////////////// + template <typename TagT, typename IdT> + inline void + object_with_id_base<TagT, IdT>::release_object_id(IdT id) + { + id_supply->release(id); + } + + ////////////////////////////////// +#ifdef BOOST_SPIRIT_THREADSAFE + template <typename TagT, typename IdT> + inline boost::mutex & + object_with_id_base<TagT, IdT>::mutex_instance() + { + static boost::mutex mutex; + return mutex; + } +#endif + + ////////////////////////////////// +#ifdef BOOST_SPIRIT_THREADSAFE + template <typename TagT, typename IdT> + inline void + object_with_id_base<TagT, IdT>::mutex_init() + { + mutex_instance(); + } +#endif + + } // namespace impl + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#endif diff --git a/boost/spirit/home/classic/core/non_terminal/impl/rule.ipp b/boost/spirit/home/classic/core/non_terminal/impl/rule.ipp new file mode 100644 index 0000000000..9f10306f7c --- /dev/null +++ b/boost/spirit/home/classic/core/non_terminal/impl/rule.ipp @@ -0,0 +1,420 @@ +/*============================================================================= + Copyright (c) 1998-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) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_RULE_IPP) +#define BOOST_SPIRIT_RULE_IPP + +#if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1 +#include <boost/preprocessor/repeat.hpp> +#include <boost/preprocessor/repeat_from_to.hpp> +#include <boost/preprocessor/enum_params.hpp> +#include <boost/preprocessor/enum_params_with_defaults.hpp> +#include <boost/preprocessor/facilities/intercept.hpp> +#include <boost/preprocessor/inc.hpp> +#include <boost/preprocessor/cat.hpp> +#endif + +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/core/scanner/scanner.hpp> +#include <boost/spirit/home/classic/core/non_terminal/parser_context.hpp> +#include <boost/spirit/home/classic/core/non_terminal/parser_id.hpp> +#include <boost/type_traits/is_base_and_derived.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +#if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1 + + template < + BOOST_PP_ENUM_BINARY_PARAMS( + BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT, + typename ScannerT, = mpl::void_ BOOST_PP_INTERCEPT + ) + > + struct scanner_list; + +#endif // BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1 + + /////////////////////////////////////////////////////////////////////////// + namespace impl + { + template <typename BaseT, typename DefaultT + , typename T0, typename T1, typename T2> + struct get_param + { + typedef typename mpl::if_< + is_base_and_derived<BaseT, T0> + , T0 + , typename mpl::if_< + is_base_and_derived<BaseT, T1> + , T1 + , typename mpl::if_< + is_base_and_derived<BaseT, T2> + , T2 + , DefaultT + >::type + >::type + >::type type; + }; + + template <typename T0, typename T1, typename T2> + struct get_context + { + typedef typename get_param< + parser_context_base, parser_context<>, T0, T1, T2>::type + type; + }; + + template <typename T0, typename T1, typename T2> + struct get_tag + { + typedef typename get_param< + parser_tag_base, parser_address_tag, T0, T1, T2>::type + type; + }; + + template <typename T0, typename T1, typename T2> + struct get_scanner + { + typedef typename get_param< + scanner_base, scanner<>, T0, T1, T2>::type + type; + }; + + /////////////////////////////////////////////////////////////////////// + // + // rule_base class + // + // The rule_base class implements the basic plumbing for rules + // minus the storage mechanism. It is up to the derived class + // to actually store the definition somewhere. The rule_base + // class assumes that the derived class provides a get() function + // that will return a pointer to a parser. The get() function + // may return NULL. See rule below for details. + // + // <<< For framework use only. Not for public consumption. >>> + // + /////////////////////////////////////////////////////////////////////// + template < + typename DerivedT // derived class + , typename EmbedT // how derived class is embedded + , typename T0 = nil_t // see rule class + , typename T1 = nil_t // see rule class + , typename T2 = nil_t // see rule class + > + class rule_base; // forward declaration + + class rule_base_access + { +#if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) \ + || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) + public: // YUCK! +#else + template < + typename DerivedT + , typename EmbedT + , typename T0 + , typename T1 + , typename T2 + > + friend class rule_base; +#endif + template <typename RuleT> + static typename RuleT::abstract_parser_t* + get(RuleT const& r) + { + return r.get(); + } + }; + + template < + typename DerivedT // derived class + , typename EmbedT // how derived class is embedded + , typename T0 // see rule class + , typename T1 // see rule class + , typename T2 // see rule class + > + class rule_base + : public parser<DerivedT> + , public impl::get_context<T0, T1, T2>::type::base_t + , public context_aux< + typename impl::get_context<T0, T1, T2>::type, DerivedT> + , public impl::get_tag<T0, T1, T2>::type + { + public: + + typedef typename impl::get_scanner<T0, T1, T2>::type scanner_t; + typedef typename impl::get_context<T0, T1, T2>::type context_t; + typedef typename impl::get_tag<T0, T1, T2>::type tag_t; + + typedef EmbedT embed_t; + typedef typename context_t::context_linker_t linked_context_t; + typedef typename linked_context_t::attr_t attr_t; + + template <typename ScannerT> + struct result + { + typedef typename match_result<ScannerT, attr_t>::type type; + }; + + template <typename ScannerT> + typename parser_result<DerivedT, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef parser_scanner_linker<ScannerT> linked_scanner_t; + typedef typename parser_result<DerivedT, ScannerT>::type result_t; + BOOST_SPIRIT_CONTEXT_PARSE( + scan, *this, linked_scanner_t, linked_context_t, result_t); + } + + template <typename ScannerT> + typename parser_result<DerivedT, ScannerT>::type + parse_main(ScannerT const& scan) const + { + typename parser_result<DerivedT, ScannerT>::type hit; + + // MWCW 8.3 needs this cast to be done through a pointer, + // not a reference. Otherwise, it will silently construct + // a temporary, causing an infinite runtime recursion. + DerivedT const* derived_this = static_cast<DerivedT const*>(this); + + if (rule_base_access::get(*derived_this)) + { + typename ScannerT::iterator_t s(scan.first); + hit = rule_base_access::get(*derived_this) + ->do_parse_virtual(scan); + scan.group_match(hit, this->id(), s, scan.first); + } + else + { + hit = scan.no_match(); + } + return hit; + } + }; + + /////////////////////////////////////////////////////////////////////// + // + // abstract_parser class + // + /////////////////////////////////////////////////////////////////////// + template <typename ScannerT, typename AttrT> + struct abstract_parser + { + abstract_parser() {} + virtual ~abstract_parser() {} + + virtual typename match_result<ScannerT, AttrT>::type + do_parse_virtual(ScannerT const& scan) const = 0; + + virtual abstract_parser* + clone() const = 0; + }; + + /////////////////////////////////////////////////////////////////////// + // + // concrete_parser class + // + /////////////////////////////////////////////////////////////////////// +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(push) +#pragma warning(disable:4512) //assignment operator could not be generated +#endif + + template <typename ParserT, typename ScannerT, typename AttrT> + struct concrete_parser : abstract_parser<ScannerT, AttrT> + { + concrete_parser(ParserT const& p_) : p(p_) {} + virtual ~concrete_parser() {} + + virtual typename match_result<ScannerT, AttrT>::type + do_parse_virtual(ScannerT const& scan) const + { + return p.parse(scan); + } + + virtual abstract_parser<ScannerT, AttrT>* + clone() const + { + return new concrete_parser(p); + } + + typename ParserT::embed_t p; + }; + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(pop) +#endif + +#if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1 + + /////////////////////////////////////////////////////////////////////// + // + // This generates partial specializations for the class + // + // abstract_parser + // + // with an increasing number of different ScannerT template parameters + // and corresponding do_parse_virtual function declarations for each + // of the different required scanner types: + // + // template <typename ScannerT0, ..., typename AttrT> + // struct abstract_parser<scanner_list<ScannerT0, ...>, AttrT> + // { + // abstract_parser() {} + // virtual ~abstract_parser() {} + // + // virtual typename match_result<ScannerT0, AttrT>::type + // do_parse_virtual(ScannerT0 const &scan) const = 0; + // + // virtual abstract_parser* + // clone() const = 0; + // + // ... + // }; + // + /////////////////////////////////////////////////////////////////////// + #define BOOST_SPIRIT_RULE_ENUM_DOPARSE_A(z, N, _) \ + virtual typename match_result< \ + BOOST_PP_CAT(ScannerT, N), AttrT \ + >::type \ + do_parse_virtual( \ + BOOST_PP_CAT(ScannerT, N) const& scan) const = 0; \ + + #define BOOST_SPIRIT_ENUM_ABSTRACT_PARSERS(z, N, _) \ + template < \ + BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), typename ScannerT), \ + typename AttrT \ + > \ + struct abstract_parser< \ + scanner_list< \ + BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), ScannerT) \ + >, \ + AttrT \ + > \ + { \ + abstract_parser() {} \ + virtual ~abstract_parser() {} \ + \ + BOOST_PP_REPEAT_ ## z( \ + BOOST_PP_INC(N), BOOST_SPIRIT_RULE_ENUM_DOPARSE_A, _) \ + \ + virtual abstract_parser* \ + clone() const = 0; \ + }; \ + + BOOST_PP_REPEAT_FROM_TO(1, BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT, + BOOST_SPIRIT_ENUM_ABSTRACT_PARSERS, _) + + #undef BOOST_SPIRIT_RULE_ENUM_DOPARSE_A + #undef BOOST_SPIRIT_ENUM_ABSTRACT_PARSERS + /////////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////////// + // + // This generates partial specializations for the class + // + // concrete_parser + // + // with an increasing number of different ScannerT template parameters + // and corresponding do_parse_virtual function declarations for each + // of the different required scanner types: + // + // template < + // typename ParserT, typename ScannerT0, ..., typename AttrT + // > + // struct concrete_parser< + // ParserT, scanner_list<ScannerT0, ...>, AttrT + // > + // : public abstract_parser<scanner_list<ScannerT0, ...>, AttrT> + // { + // concrete_parser(ParserT const& p_) : p(p_) {} + // virtual ~concrete_parser() {} + // + // virtual typename match_result<ScannerT0, AttrT>::type + // do_parse_virtual(ScannerT0 const &scan) const + // { return p.parse(scan); } + // + // virtual abstract_parser<scanner_list<ScannerT0, ...>, AttrT>* + // clone() const + // { + // return new concrete_parser(p); + // } + // + // ... + // + // typename ParserT::embed_t p; + // }; + // + /////////////////////////////////////////////////////////////////////// + #define BOOST_SPIRIT_RULE_ENUM_DOPARSE_C(z, N, _) \ + virtual typename match_result< \ + BOOST_PP_CAT(ScannerT, N), AttrT \ + >::type \ + do_parse_virtual( \ + BOOST_PP_CAT(ScannerT, N) const& scan) const \ + { return p.parse(scan); } \ + + #define BOOST_SPIRIT_ENUM_CONCRETE_PARSERS(z, N, _) \ + template < \ + typename ParserT, \ + BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), typename ScannerT), \ + typename AttrT \ + > \ + struct concrete_parser< \ + ParserT, \ + scanner_list< \ + BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), ScannerT) \ + >, \ + AttrT \ + > \ + : abstract_parser< \ + scanner_list< \ + BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), ScannerT) \ + >, \ + AttrT \ + > \ + { \ + concrete_parser(ParserT const& p_) : p(p_) {} \ + virtual ~concrete_parser() {} \ + \ + BOOST_PP_REPEAT_ ## z( \ + BOOST_PP_INC(N), BOOST_SPIRIT_RULE_ENUM_DOPARSE_C, _) \ + \ + virtual abstract_parser< \ + scanner_list< \ + BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), ScannerT) \ + >, \ + AttrT \ + >* \ + clone() const \ + { \ + return new concrete_parser(p); \ + } \ + \ + typename ParserT::embed_t p; \ + }; \ + + BOOST_PP_REPEAT_FROM_TO(1, BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT, + BOOST_SPIRIT_ENUM_CONCRETE_PARSERS, _) + + #undef BOOST_SPIRIT_ENUM_CONCRETE_PARSERS + #undef BOOST_SPIRIT_RULE_ENUM_DOPARSE_C + /////////////////////////////////////////////////////////////////////// + +#endif // BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1 + + } // namespace impl + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#endif diff --git a/boost/spirit/home/classic/core/non_terminal/impl/static.hpp b/boost/spirit/home/classic/core/non_terminal/impl/static.hpp new file mode 100644 index 0000000000..89c6d29c3c --- /dev/null +++ b/boost/spirit/home/classic/core/non_terminal/impl/static.hpp @@ -0,0 +1,120 @@ +/*============================================================================= + Copyright (c) 2006 Joao Abecasis + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_STATIC_HPP) +#define BOOST_SPIRIT_STATIC_HPP + +#include <boost/noncopyable.hpp> +#include <boost/call_traits.hpp> +#include <boost/aligned_storage.hpp> + +#include <boost/type_traits/add_pointer.hpp> +#include <boost/type_traits/alignment_of.hpp> + +#include <boost/thread/once.hpp> + +#include <memory> // for placement new + +#include <boost/spirit/home/classic/namespace.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + // + // Provides thread-safe initialization of a single static instance of T. + // + // This instance is guaranteed to be constructed on static storage in a + // thread-safe manner, on the first call to the constructor of static_. + // + // Requirements: + // T is default constructible + // (There's an alternate implementation that relaxes this + // requirement -- Joao Abecasis) + // T::T() MUST not throw! + // this is a requirement of boost::call_once. + // + template <class T, class Tag> + struct static_ + : boost::noncopyable + { + private: + + struct destructor + { + ~destructor() + { + static_::get_address()->~value_type(); + } + }; + + struct default_ctor + { + static void construct() + { + ::new (static_::get_address()) value_type(); + static destructor d; + } + }; + + public: + + typedef T value_type; + typedef typename boost::call_traits<T>::reference reference; + typedef typename boost::call_traits<T>::const_reference const_reference; + + static_(Tag = Tag()) + { + boost::call_once(&default_ctor::construct, constructed_); + } + + operator reference() + { + return this->get(); + } + + operator const_reference() const + { + return this->get(); + } + + reference get() + { + return *this->get_address(); + } + + const_reference get() const + { + return *this->get_address(); + } + + private: + typedef typename boost::add_pointer<value_type>::type pointer; + + static pointer get_address() + { + return static_cast<pointer>(data_.address()); + } + + typedef boost::aligned_storage<sizeof(value_type), + boost::alignment_of<value_type>::value> storage_type; + + static storage_type data_; + static once_flag constructed_; + }; + + template <class T, class Tag> + typename static_<T, Tag>::storage_type static_<T, Tag>::data_; + + template <class T, class Tag> + once_flag static_<T, Tag>::constructed_ = BOOST_ONCE_INIT; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif // include guard diff --git a/boost/spirit/home/classic/core/non_terminal/impl/subrule.ipp b/boost/spirit/home/classic/core/non_terminal/impl/subrule.ipp new file mode 100644 index 0000000000..4651cc31ec --- /dev/null +++ b/boost/spirit/home/classic/core/non_terminal/impl/subrule.ipp @@ -0,0 +1,211 @@ +/*============================================================================= + Copyright (c) 2002-2003 Joel de Guzman + Copyright (c) 2002-2003 Hartmut Kaiser + 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) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_SUBRULE_IPP) +#define BOOST_SPIRIT_SUBRULE_IPP + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + template <typename FirstT, typename RestT> + struct subrule_list; + + template <int ID, typename DefT, typename ContextT> + struct subrule_parser; + + namespace impl { + + #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + + template <int N, typename ListT> + struct get_subrule; + + template <int N, typename ListT> + struct get_subrule_chooser + { + static ListT t(); + static char test(nil_t); + static int test(...); + + // Set value to + // 0: ListT is empty + // 1: ListT's first item has same ID + // 2: ListT's first item has a different ID + + enum + { + id = ListT::first_t::id, + is_same_id = N == id, + is_nil_t = sizeof(char) == sizeof(test(t())), + value = is_nil_t ? 0 : (is_same_id ? 1 : 2) + }; + }; + + template <int N> + struct subrule_chooser; + + template <> + struct subrule_chooser<0> + { + // First case. ListT is empty + + template <int N, typename ListT> + struct result + { typedef nil_t type; }; + }; + + template <> + struct subrule_chooser<1> + { + // Second case. ListT is non-empty and the list's + // first item has the ID we are looking for. + + template <int N, typename ListT> + struct result + { typedef typename ListT::first_t::def_t type; }; + }; + + template <> + struct subrule_chooser<2> + { + // Third case. ListT is non-empty but the list's + // first item does not have the ID we are looking for. + + template <int N, typename ListT> + struct result + { typedef typename get_subrule<N, ListT::rest_t>::type type; }; + }; + + template <int N, typename ListT> + struct get_subrule + { + enum { n = get_subrule_chooser<N, ListT>::value }; + typedef typename subrule_chooser<n>::template + result<N, ListT>::type type; + }; + + #else + + template <int N, typename ListT> + struct get_subrule + { + // First case. ListT is non-empty but the list's + // first item does not have the ID we are looking for. + + typedef typename get_subrule<N, typename ListT::rest_t>::type type; + }; + + template <int ID, typename DefT, typename ContextT, typename RestT> + struct get_subrule< + ID, + subrule_list< + subrule_parser<ID, DefT, ContextT>, + RestT> > + { + // Second case. ListT is non-empty and the list's + // first item has the ID we are looking for. + + typedef DefT type; + }; + + template <int ID> + struct get_subrule<ID, nil_t> + { + // Third case. ListT is empty + typedef nil_t type; + }; + + #endif + + template <typename T1, typename T2> + struct get_result_t { + + // If the result type dictated by the context is nil_t (no closures + // present), then the whole subrule_parser return type is equal to + // the return type of the right hand side of this subrule_parser, + // otherwise it is equal to the dictated return value. + + typedef typename mpl::if_< + boost::is_same<T1, nil_t>, T2, T1 + >::type type; + }; + + template <int ID, typename ScannerT, typename ContextResultT> + struct get_subrule_result + { + typedef typename + impl::get_subrule<ID, typename ScannerT::list_t>::type + parser_t; + + typedef typename parser_result<parser_t, ScannerT>::type + def_result_t; + + typedef typename match_result<ScannerT, ContextResultT>::type + context_result_t; + + typedef typename get_result_t<context_result_t, def_result_t>::type + type; + }; + + template <typename DefT, typename ScannerT, typename ContextResultT> + struct get_subrule_parser_result + { + typedef typename parser_result<DefT, ScannerT>::type + def_result_t; + + typedef typename match_result<ScannerT, ContextResultT>::type + context_result_t; + + typedef typename get_result_t<context_result_t, def_result_t>::type + type; + }; + + template <typename SubruleT, int ID> + struct same_subrule_id + { + BOOST_STATIC_CONSTANT(bool, value = (SubruleT::id == ID)); + }; + + template <typename RT, typename ScannerT, int ID> + struct parse_subrule + { + template <typename ListT> + static void + do_parse(RT& r, ScannerT const& scan, ListT const& list, mpl::true_) + { + r = list.first.rhs.parse(scan); + } + + template <typename ListT> + static void + do_parse(RT& r, ScannerT const& scan, ListT const& list, mpl::false_) + { + typedef typename ListT::rest_t::first_t subrule_t; + mpl::bool_<same_subrule_id<subrule_t, ID>::value> same_id; + do_parse(r, scan, list.rest, same_id); + } + + static void + do_(RT& r, ScannerT const& scan) + { + typedef typename ScannerT::list_t::first_t subrule_t; + mpl::bool_<same_subrule_id<subrule_t, ID>::value> same_id; + do_parse(r, scan, scan.list, same_id); + } + }; + +} + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit::impl + +#endif + diff --git a/boost/spirit/home/classic/core/non_terminal/parser_context.hpp b/boost/spirit/home/classic/core/non_terminal/parser_context.hpp new file mode 100644 index 0000000000..2f7dd23e80 --- /dev/null +++ b/boost/spirit/home/classic/core/non_terminal/parser_context.hpp @@ -0,0 +1,150 @@ +/*============================================================================= + Copyright (c) 2002-2003 Joel de Guzman + Copyright (c) 2002-2003 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_PARSER_CONTEXT_HPP) +#define BOOST_SPIRIT_PARSER_CONTEXT_HPP + +/////////////////////////////////////////////////////////////////////////////// +namespace boost +{ + namespace spirit + { + BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + + /////////////////////////////////////////////////////////////////////////// + // + // default_parser_context_base class { default context base } + // + /////////////////////////////////////////////////////////////////////////// + struct default_parser_context_base + { + template <typename DerivedT> + struct aux {}; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // parser_context_base class { base class of all context classes } + // + /////////////////////////////////////////////////////////////////////////// + struct parser_context_base {}; + + /////////////////////////////////////////////////////////////////////////// + // + // parser_context class { default context } + // + /////////////////////////////////////////////////////////////////////////// + struct nil_t; + template<typename ContextT> struct parser_context_linker; + + template<typename AttrT = nil_t> + struct parser_context : parser_context_base + { + typedef AttrT attr_t; + typedef default_parser_context_base base_t; + typedef parser_context_linker<parser_context<AttrT> > context_linker_t; + + template <typename ParserT> + parser_context(ParserT const&) {} + + template <typename ParserT, typename ScannerT> + void + pre_parse(ParserT const&, ScannerT const&) {} + + template <typename ResultT, typename ParserT, typename ScannerT> + ResultT& + post_parse(ResultT& hit, ParserT const&, ScannerT const&) + { return hit; } + }; + + /////////////////////////////////////////////////////////////////////////// + // + // context_aux class + // + // context_aux<ContextT, DerivedT> is a class derived from the + // ContextT's nested base_t::base<DerivedT> template class. (see + // default_parser_context_base::aux for an example). + // + // Basically, this class provides ContextT dependent optional + // functionality to the derived class DerivedT through the CRTP + // idiom (Curiously recurring template pattern). + // + /////////////////////////////////////////////////////////////////////////// + template <typename ContextT, typename DerivedT> + struct context_aux : public ContextT::base_t::template aux<DerivedT> {}; + + /////////////////////////////////////////////////////////////////////////// + // + // parser_scanner_linker and parser_scanner_linker classes + // { helper templates for the rule extensibility } + // + // This classes can be 'overloaded' (defined elsewhere), to plug + // in additional functionality into the non-terminal parsing process. + // + /////////////////////////////////////////////////////////////////////////// + #if !defined(BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED) + #define BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED + + template<typename ScannerT> + struct parser_scanner_linker : public ScannerT + { + parser_scanner_linker(ScannerT const scan_) : ScannerT(scan_) {} + }; + + #endif // !defined(BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED) + + ////////////////////////////////// + #if !defined(BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED) + #define BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED + + template<typename ContextT> + struct parser_context_linker : public ContextT + { + template <typename ParserT> + parser_context_linker(ParserT const& p) + : ContextT(p) {} + + template <typename ParserT, typename ScannerT> + void pre_parse(ParserT const& p, ScannerT const& scan) + { ContextT::pre_parse(p, scan); } + + template <typename ResultT, typename ParserT, typename ScannerT> + ResultT& + post_parse(ResultT& hit, ParserT const& p, ScannerT const& scan) + { return ContextT::post_parse(hit, p, scan); } + }; + + #endif // !defined(BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED) + + /////////////////////////////////////////////////////////////////////////// + // + // BOOST_SPIRIT_CONTEXT_PARSE helper macro + // + // The original implementation uses a template class. However, we + // need to lessen the template instantiation depth to help inferior + // compilers that sometimes choke on deep template instantiations. + // The objective is to avoid code redundancy. A macro, in this case + // is an obvious solution. Sigh! + // + // WARNING: INTERNAL USE ONLY. NOT FOR PUBLIC CONSUMPTION. + // + /////////////////////////////////////////////////////////////////////////// + #define BOOST_SPIRIT_CONTEXT_PARSE(scan, this_, scanner_t, context_t, result_t) \ + scanner_t scan_wrap(scan); \ + context_t context_wrap(this_); \ + context_wrap.pre_parse(this_, scan_wrap); \ + result_t hit = parse_main(scan); \ + return context_wrap.post_parse(hit, this_, scan_wrap); + + BOOST_SPIRIT_CLASSIC_NAMESPACE_END + + } // namespace spirit +} // namespace boost + +#endif diff --git a/boost/spirit/home/classic/core/non_terminal/parser_id.hpp b/boost/spirit/home/classic/core/non_terminal/parser_id.hpp new file mode 100644 index 0000000000..bc465dceac --- /dev/null +++ b/boost/spirit/home/classic/core/non_terminal/parser_id.hpp @@ -0,0 +1,122 @@ +/*============================================================================= + Copyright (c) 2001-2003 Joel de Guzman + Copyright (c) 2001 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) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_PARSER_ID_HPP) +#define BOOST_SPIRIT_PARSER_ID_HPP + +#if defined(BOOST_SPIRIT_DEBUG) +# include <ostream> +#endif +#include <boost/spirit/home/classic/namespace.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // parser_id class + // + /////////////////////////////////////////////////////////////////////////// + class parser_id + { + public: + parser_id() : p(0) {} + explicit parser_id(void const* prule) : p(prule) {} + parser_id(std::size_t l_) : l(l_) {} + + bool operator==(parser_id const& x) const { return p == x.p; } + bool operator!=(parser_id const& x) const { return !(*this == x); } + bool operator<(parser_id const& x) const { return p < x.p; } + std::size_t to_long() const { return l; } + + private: + + union + { + void const* p; + std::size_t l; + }; + }; + + #if defined(BOOST_SPIRIT_DEBUG) + inline std::ostream& + operator<<(std::ostream& out, parser_id const& rid) + { + out << (unsigned int)rid.to_long(); + return out; + } + #endif + + /////////////////////////////////////////////////////////////////////////// + // + // parser_tag_base class: base class of all parser tags + // + /////////////////////////////////////////////////////////////////////////// + struct parser_tag_base {}; + + /////////////////////////////////////////////////////////////////////////// + // + // parser_address_tag class: tags a parser with its address + // + /////////////////////////////////////////////////////////////////////////// + struct parser_address_tag : parser_tag_base + { + parser_id id() const + { return parser_id(reinterpret_cast<std::size_t>(this)); } + }; + + /////////////////////////////////////////////////////////////////////////// + // + // parser_tag class: tags a parser with an integer ID + // + /////////////////////////////////////////////////////////////////////////// + template <int N> + struct parser_tag : parser_tag_base + { + static parser_id id() + { return parser_id(std::size_t(N)); } + }; + + /////////////////////////////////////////////////////////////////////////// + // + // dynamic_parser_tag class: tags a parser with a dynamically changeable + // integer ID + // + /////////////////////////////////////////////////////////////////////////// + class dynamic_parser_tag : public parser_tag_base + { + public: + + dynamic_parser_tag() + : tag(std::size_t(0)) {} + + parser_id + id() const + { + return + tag.to_long() + ? tag + : parser_id(reinterpret_cast<std::size_t>(this)); + } + + void set_id(parser_id id_) { tag = id_; } + + private: + + parser_id tag; + }; + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + diff --git a/boost/spirit/home/classic/core/non_terminal/rule.hpp b/boost/spirit/home/classic/core/non_terminal/rule.hpp new file mode 100644 index 0000000000..e905689431 --- /dev/null +++ b/boost/spirit/home/classic/core/non_terminal/rule.hpp @@ -0,0 +1,175 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_RULE_HPP) +#define BOOST_SPIRIT_RULE_HPP + +#include <boost/static_assert.hpp> + +/////////////////////////////////////////////////////////////////////////////// +// +// Spirit predefined maximum number of simultaneously usable different +// scanner types. +// +// This limit defines the maximum number of of possible different scanner +// types for which a specific rule<> may be used. If this isn't defined, a +// rule<> may be used with one scanner type only (multiple scanner support +// is disabled). +// +/////////////////////////////////////////////////////////////////////////////// +#if !defined(BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT) +# define BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT 1 +#endif + +// Ensure a meaningful maximum number of simultaneously usable scanner types +BOOST_STATIC_ASSERT(BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 0); + +#include <boost/scoped_ptr.hpp> +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/non_terminal/impl/rule.ipp> + +#if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1 +# include <boost/preprocessor/enum_params.hpp> +#endif + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +#if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1 + + /////////////////////////////////////////////////////////////////////////// + // + // scanner_list (a fake scanner) + // + // Typically, rules are tied to a specific scanner type and + // a particular rule cannot be used with anything else. Sometimes + // there's a need for rules that can accept more than one scanner + // type. The scanner_list<S0, ...SN> can be used as a template + // parameter to the rule class to specify up to the number of + // scanner types defined by the BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT + // constant. Example: + // + // rule<scanner_list<ScannerT0, ScannerT1> > r; + // + // *** This feature is available only to compilers that support + // partial template specialization. *** + // + /////////////////////////////////////////////////////////////////////////// + template < + BOOST_PP_ENUM_PARAMS( + BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT, + typename ScannerT + ) + > + struct scanner_list : scanner_base {}; + +#endif + + /////////////////////////////////////////////////////////////////////////// + // + // rule class + // + // The rule is a polymorphic parser that acts as a named place- + // holder capturing the behavior of an EBNF expression assigned to + // it. + // + // The rule is a template class parameterized by: + // + // 1) scanner (scanner_t, see scanner.hpp), + // 2) the rule's context (context_t, see parser_context.hpp) + // 3) an arbitrary tag (tag_t, see parser_id.hpp) that allows + // a rule to be tagged for identification. + // + // These template parameters may be specified in any order. The + // scanner will default to scanner<> when it is not specified. + // The context will default to parser_context when not specified. + // The tag will default to parser_address_tag when not specified. + // + // The definition of the rule (its right hand side, RHS) held by + // the rule through a scoped_ptr. When a rule is seen in the RHS + // of an assignment or copy construction EBNF expression, the rule + // is held by the LHS rule by reference. + // + /////////////////////////////////////////////////////////////////////////// + template < + typename T0 = nil_t + , typename T1 = nil_t + , typename T2 = nil_t + > + class rule + : public impl::rule_base< + rule<T0, T1, T2> + , rule<T0, T1, T2> const& + , T0, T1, T2> + { + public: + + typedef rule<T0, T1, T2> self_t; + typedef impl::rule_base< + self_t + , self_t const& + , T0, T1, T2> + base_t; + + typedef typename base_t::scanner_t scanner_t; + typedef typename base_t::attr_t attr_t; + typedef impl::abstract_parser<scanner_t, attr_t> abstract_parser_t; + + rule() : ptr() {} + ~rule() {} + + rule(rule const& r) + : ptr(new impl::concrete_parser<rule, scanner_t, attr_t>(r)) {} + + template <typename ParserT> + rule(ParserT const& p) + : ptr(new impl::concrete_parser<ParserT, scanner_t, attr_t>(p)) {} + + template <typename ParserT> + rule& operator=(ParserT const& p) + { + ptr.reset(new impl::concrete_parser<ParserT, scanner_t, attr_t>(p)); + return *this; + } + + rule& operator=(rule const& r) + { + ptr.reset(new impl::concrete_parser<rule, scanner_t, attr_t>(r)); + return *this; + } + + rule<T0, T1, T2> + copy() const + { + return rule<T0, T1, T2>(ptr.get() ? ptr->clone() : 0); + } + + private: + friend class impl::rule_base_access; + + abstract_parser_t* + get() const + { + return ptr.get(); + } + + rule(abstract_parser_t* ptr_) + : ptr(ptr_) {} + + rule(abstract_parser_t const* ptr_) + : ptr(ptr_) {} + + scoped_ptr<abstract_parser_t> ptr; + }; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif diff --git a/boost/spirit/home/classic/core/non_terminal/subrule.hpp b/boost/spirit/home/classic/core/non_terminal/subrule.hpp new file mode 100644 index 0000000000..8b25d8d0e3 --- /dev/null +++ b/boost/spirit/home/classic/core/non_terminal/subrule.hpp @@ -0,0 +1,300 @@ +/*============================================================================= + Copyright (c) 2002-2003 Joel de Guzman + Copyright (c) 2002-2003 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_SUBRULE_HPP) +#define BOOST_SPIRIT_SUBRULE_HPP + +#include <boost/config.hpp> +#include <boost/static_assert.hpp> + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/core/non_terminal/parser_context.hpp> + +#include <boost/spirit/home/classic/core/non_terminal/subrule_fwd.hpp> +#include <boost/spirit/home/classic/core/non_terminal/impl/subrule.ipp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // subrules_scanner class + // + /////////////////////////////////////////////////////////////////////////// + template <typename ScannerT, typename ListT> + struct subrules_scanner : public ScannerT + { + typedef ScannerT scanner_t; + typedef ListT list_t; + typedef subrules_scanner<ScannerT, ListT> self_t; + + subrules_scanner(ScannerT const& scan, ListT const& list_) + : ScannerT(scan), list(list_) {} + + template <typename PoliciesT> + struct rebind_policies + { + typedef typename rebind_scanner_policies<ScannerT, PoliciesT>::type + rebind_scanner; + typedef subrules_scanner<rebind_scanner, ListT> type; + }; + + template <typename PoliciesT> + subrules_scanner< + typename rebind_scanner_policies<ScannerT, PoliciesT>::type, + ListT> + change_policies(PoliciesT const& policies) const + { + typedef subrules_scanner< + BOOST_DEDUCED_TYPENAME + rebind_scanner_policies<ScannerT, PoliciesT>::type, + ListT> + subrules_scanner_t; + + return subrules_scanner_t( + ScannerT::change_policies(policies), + list); + } + + template <typename IteratorT> + struct rebind_iterator + { + typedef typename rebind_scanner_iterator<ScannerT, IteratorT>::type + rebind_scanner; + typedef subrules_scanner<rebind_scanner, ListT> type; + }; + + template <typename IteratorT> + subrules_scanner< + typename rebind_scanner_iterator<ScannerT, IteratorT>::type, + ListT> + change_iterator(IteratorT const& first, IteratorT const &last) const + { + typedef subrules_scanner< + BOOST_DEDUCED_TYPENAME + rebind_scanner_iterator<ScannerT, IteratorT>::type, + ListT> + subrules_scanner_t; + + return subrules_scanner_t( + ScannerT::change_iterator(first, last), + list); + } + + ListT const& list; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // subrule_scanner type computer class + // + // This computer ensures that the scanner will not be recursively + // instantiated if it's not needed. + // + /////////////////////////////////////////////////////////////////////////// + template <typename ScannerT, typename ListT> + struct subrules_scanner_finder + { + typedef subrules_scanner<ScannerT, ListT> type; + }; + + template <typename ScannerT, typename ListT> + struct subrules_scanner_finder<subrules_scanner<ScannerT, ListT>, ListT> + { + typedef subrules_scanner<ScannerT, ListT> type; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // subrule_list class + // + /////////////////////////////////////////////////////////////////////////// + template <typename FirstT, typename RestT> + struct subrule_list : public parser<subrule_list<FirstT, RestT> > + { + typedef subrule_list<FirstT, RestT> self_t; + typedef FirstT first_t; + typedef RestT rest_t; + + subrule_list(FirstT const& first_, RestT const& rest_) + : first(first_), rest(rest_) {} + + template <typename ScannerT> + struct result + { + typedef typename parser_result<FirstT, ScannerT>::type type; + }; + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename subrules_scanner_finder<ScannerT, self_t>::type + subrules_scanner_t; + subrules_scanner_t g_arg(scan, *this); + return first.start.parse(g_arg); + } + + template <int ID, typename DefT, typename ContextT> + subrule_list< + FirstT, + subrule_list< + subrule_parser<ID, DefT, ContextT>, + RestT> > + operator,(subrule_parser<ID, DefT, ContextT> const& rhs_) + { + return subrule_list< + FirstT, + subrule_list< + subrule_parser<ID, DefT, ContextT>, + RestT> >( + first, + subrule_list< + subrule_parser<ID, DefT, ContextT>, + RestT>(rhs_, rest)); + } + + FirstT first; + RestT rest; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // subrule_parser class + // + /////////////////////////////////////////////////////////////////////////// + template <int ID, typename DefT, typename ContextT> + struct subrule_parser + : public parser<subrule_parser<ID, DefT, ContextT> > + { + typedef subrule_parser<ID, DefT, ContextT> self_t; + typedef subrule<ID, ContextT> subrule_t; + typedef DefT def_t; + + BOOST_STATIC_CONSTANT(int, id = ID); + + template <typename ScannerT> + struct result + { + typedef typename + impl::get_subrule_parser_result< + DefT, ScannerT, typename subrule_t::attr_t>::type type; + }; + + subrule_parser(subrule_t const& start_, DefT const& rhs_) + : rhs(rhs_), start(start_) {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + // This will only be called when parsing single subrules. + typedef subrule_list<self_t, nil_t> list_t; + typedef subrules_scanner<ScannerT, list_t> scanner_t; + + list_t list(*this, nil_t()); + scanner_t g_arg(scan, list); + return start.parse(g_arg); + } + + template <int ID2, typename DefT2, typename ContextT2> + inline subrule_list< + self_t, + subrule_list< + subrule_parser<ID2, DefT2, ContextT2>, + nil_t> > + operator,(subrule_parser<ID2, DefT2, ContextT2> const& rhs) const + { + return subrule_list< + self_t, + subrule_list< + subrule_parser<ID2, DefT2, ContextT2>, + nil_t> >( + *this, + subrule_list< + subrule_parser<ID2, DefT2, ContextT2>, nil_t>( + rhs, nil_t())); + } + + typename DefT::embed_t rhs; + subrule_t const& start; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // subrule class + // + /////////////////////////////////////////////////////////////////////////// + template <int ID, typename ContextT> + struct subrule + : public parser<subrule<ID, ContextT> > + , public ContextT::base_t + , public context_aux<ContextT, subrule<ID, ContextT> > + { + typedef subrule<ID, ContextT> self_t; + typedef subrule<ID, ContextT> const& embed_t; + + typedef typename ContextT::context_linker_t context_t; + typedef typename context_t::attr_t attr_t; + + BOOST_STATIC_CONSTANT(int, id = ID); + + template <typename ScannerT> + struct result + { + typedef typename + impl::get_subrule_result<ID, ScannerT, attr_t>::type type; + }; + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse_main(ScannerT const& scan) const + { + typedef typename parser_result<self_t, ScannerT>::type result_t; + result_t result_; + impl::parse_subrule<result_t, ScannerT, ID>:: + do_(result_, scan); + return result_; + } + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename parser_result<self_t, ScannerT>::type result_t; + typedef parser_scanner_linker<ScannerT> scanner_t; + BOOST_SPIRIT_CONTEXT_PARSE( + scan, *this, scanner_t, context_t, result_t); + } + + template <typename DefT> + subrule_parser<ID, DefT, ContextT> + operator=(parser<DefT> const& rhs) const + { + return subrule_parser<ID, DefT, ContextT>(*this, rhs.derived()); + } + + private: + + // assignment of subrules is not allowed. Use subrules + // with identical IDs if you want to have aliases. + + subrule& operator=(subrule const&); + + template <int ID2, typename ContextT2> + subrule& operator=(subrule<ID2, ContextT2> const&); + }; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + diff --git a/boost/spirit/home/classic/core/non_terminal/subrule_fwd.hpp b/boost/spirit/home/classic/core/non_terminal/subrule_fwd.hpp new file mode 100644 index 0000000000..bb6ce87858 --- /dev/null +++ b/boost/spirit/home/classic/core/non_terminal/subrule_fwd.hpp @@ -0,0 +1,35 @@ +/*============================================================================= + Copyright (c) 2006 Tobias Schwinger + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_SUBRULE_FWD_HPP) +#define BOOST_SPIRIT_SUBRULE_FWD_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/non_terminal/parser_context.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + template <int ID, typename ContextT = parser_context<> > + struct subrule; + + template <int ID, typename DefT, typename ContextT = parser_context<> > + struct subrule_parser; + + template <typename ScannerT, typename ListT> + struct subrules_scanner; + + template <typename FirstT, typename RestT> + struct subrule_list; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + diff --git a/boost/spirit/home/classic/core/parser.hpp b/boost/spirit/home/classic/core/parser.hpp new file mode 100644 index 0000000000..8f6bc6a3ee --- /dev/null +++ b/boost/spirit/home/classic/core/parser.hpp @@ -0,0 +1,223 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_PARSER_HPP) +#define BOOST_SPIRIT_PARSER_HPP + +#include <boost/config.hpp> +#include <boost/type_traits/remove_reference.hpp> +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/scanner/scanner.hpp> +#include <boost/spirit/home/classic/core/nil.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + template <typename ParserT, typename ActionT> + class action; // forward declaration + + /////////////////////////////////////////////////////////////////////////// + // + // Parser categories + // + // Helper template classes to distinguish different types of + // parsers. The following categories are the most generic. More + // specific types may inherit from these. Each parser has a typedef + // parser_category_t that defines its category. By default, if one + // is not specified, it will inherit from the base parser class + // which typedefs its parser_category_t as plain_parser_category. + // + // - plain parser has nothing special + // - binary parser has subject a and b (e.g. alternative) + // - unary parser has single subject (e.g. kleene star) + // - action parser has an attached action parser + // + /////////////////////////////////////////////////////////////////////////// + struct plain_parser_category {}; + struct binary_parser_category : plain_parser_category {}; + struct unary_parser_category : plain_parser_category {}; + struct action_parser_category : unary_parser_category {}; + + /////////////////////////////////////////////////////////////////////////// + // + // parser_result metafunction + // + // Given a scanner type ScannerT and a parser type ParserT, the + // parser_result metafunction provides the actual result of the + // parser. + // + // Usage: + // + // typename parser_result<ParserT, ScannerT>::type + // + /////////////////////////////////////////////////////////////////////////// + template <typename ParserT, typename ScannerT> + struct parser_result + { + typedef typename boost::remove_reference<ParserT>::type parser_type; + typedef typename parser_type::template result<ScannerT>::type type; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // parser class + // + // This class is a protocol base class for all parsers. This is + // essentially an interface contract. The parser class does not + // really know how to parse anything but instead relies on the + // template parameter DerivedT (which obviously is assumed to be a + // subclass) to do the actual parsing. + // + // Concrete sub-classes inheriting from parser must have a + // corresponding member function parse(...) compatible with the + // conceptual Interface: + // + // template <typename ScannerT> + // RT parse(ScannerT const& scan) const; + // + // where RT is the desired return type of the parser and ScannerT + // scan is the scanner (see scanner.hpp). + // + // Concrete sub-classes inheriting from parser in most cases need to + // have a nested meta-function result that returns the result type + // of the parser's parse member function, given a scanner type. The + // meta-function has the form: + // + // template <typename ScannerT> + // struct result + // { + // typedef RT type; + // }; + // + // where RT is the desired return type of the parser. This is + // usually, but not always, dependent on the template parameter + // ScannerT. If a parser does not supply a result metafunction, a + // default is provided by the base parser class. + // + // The parser's derived() member function returns a reference to the + // parser as its derived object. + // + // An operator[] is provided. The operator returns a semantic action + // handler (see actions.hpp). + // + // Each parser has a typedef embed_t. This typedef specifies how a + // parser is embedded in a composite (see composite.hpp). By + // default, if one is not specified, the parser will be embedded by + // value. That is, a copy of the parser is placed as a member + // variable of the composite. Most parsers are embedded by value. In + // certain situations however, this is not desirable or possible. + // + /////////////////////////////////////////////////////////////////////////// + template <typename DerivedT> + struct parser + { + typedef DerivedT embed_t; + typedef DerivedT derived_t; + typedef plain_parser_category parser_category_t; + + template <typename ScannerT> + struct result + { + typedef typename match_result<ScannerT, nil_t>::type type; + }; + + DerivedT& derived() + { + return *static_cast<DerivedT*>(this); + } + + DerivedT const& derived() const + { + return *static_cast<DerivedT const*>(this); + } + + template <typename ActionT> + action<DerivedT, ActionT> + operator[](ActionT const& actor) const + { + return action<DerivedT, ActionT>(derived(), actor); + } + }; + + /////////////////////////////////////////////////////////////////////////// + // + // parse_info + // + // Results returned by the free parse functions: + // + // stop: points to the final parse position (i.e parsing + // processed the input up to this point). + // + // hit: true if parsing is successful. This may be full: + // the parser consumed all the input, or partial: + // the parser consumed only a portion of the input. + // + // full: true when we have a full hit (i.e the parser + // consumed all the input. + // + // length: The number of characters consumed by the parser. + // This is valid only if we have a successful hit + // (either partial or full). + // + /////////////////////////////////////////////////////////////////////////// + template <typename IteratorT = char const*> + struct parse_info + { + IteratorT stop; + bool hit; + bool full; + std::size_t length; + + parse_info( + IteratorT const& stop_ = IteratorT(), + bool hit_ = false, + bool full_ = false, + std::size_t length_ = 0) + : stop(stop_) + , hit(hit_) + , full(full_) + , length(length_) {} + + template <typename ParseInfoT> + parse_info(ParseInfoT const& pi) + : stop(pi.stop) + , hit(pi.hit) + , full(pi.full) + , length(pi.length) {} + }; + + /////////////////////////////////////////////////////////////////////////// + // + // Generic parse function + // + /////////////////////////////////////////////////////////////////////////// + template <typename IteratorT, typename DerivedT> + parse_info<IteratorT> + parse( + IteratorT const& first, + IteratorT const& last, + parser<DerivedT> const& p); + + /////////////////////////////////////////////////////////////////////////// + // + // Parse function for null terminated strings + // + /////////////////////////////////////////////////////////////////////////// + template <typename CharT, typename DerivedT> + parse_info<CharT const*> + parse( + CharT const* str, + parser<DerivedT> const& p); + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + +#include <boost/spirit/home/classic/core/impl/parser.ipp> diff --git a/boost/spirit/home/classic/core/primitives/impl/numerics.ipp b/boost/spirit/home/classic/core/primitives/impl/numerics.ipp new file mode 100644 index 0000000000..19586f1a10 --- /dev/null +++ b/boost/spirit/home/classic/core/primitives/impl/numerics.ipp @@ -0,0 +1,478 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001-2003 Hartmut Kaiser + 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_SPIRIT_NUMERICS_IPP +#define BOOST_SPIRIT_NUMERICS_IPP + +#include <boost/config/no_tr1/cmath.hpp> +#include <limits> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + struct sign_parser; // forward declaration only + + namespace impl + { + /////////////////////////////////////////////////////////////////////// + // + // Extract the prefix sign (- or +) + // + /////////////////////////////////////////////////////////////////////// + template <typename ScannerT> + bool + extract_sign(ScannerT const& scan, std::size_t& count) + { + // Extract the sign + count = 0; + bool neg = *scan == '-'; + if (neg || (*scan == '+')) + { + ++scan; + ++count; + return neg; + } + + return false; + } + + /////////////////////////////////////////////////////////////////////// + // + // Traits class for radix specific number conversion + // + // Convert a digit from character representation, ch, to binary + // representation, returned in val. + // Returns whether the conversion was successful. + // + // template<typename CharT> static bool digit(CharT ch, T& val); + // + /////////////////////////////////////////////////////////////////////// + template<const int Radix> + struct radix_traits; + + ////////////////////////////////// Binary + template<> + struct radix_traits<2> + { + template<typename CharT, typename T> + static bool digit(CharT ch, T& val) + { + val = ch - '0'; + return ('0' == ch || '1' == ch); + } + }; + + ////////////////////////////////// Octal + template<> + struct radix_traits<8> + { + template<typename CharT, typename T> + static bool digit(CharT ch, T& val) + { + val = ch - '0'; + return ('0' <= ch && ch <= '7'); + } + }; + + ////////////////////////////////// Decimal + template<> + struct radix_traits<10> + { + template<typename CharT, typename T> + static bool digit(CharT ch, T& val) + { + val = ch - '0'; + return impl::isdigit_(ch); + } + }; + + ////////////////////////////////// Hexadecimal + template<> + struct radix_traits<16> + { + template<typename CharT, typename T> + static bool digit(CharT ch, T& val) + { + if (radix_traits<10>::digit(ch, val)) + return true; + + CharT lc = impl::tolower_(ch); + if ('a' <= lc && lc <= 'f') + { + val = lc - 'a' + 10; + return true; + } + return false; + } + }; + + /////////////////////////////////////////////////////////////////////// + // + // Helper templates for encapsulation of radix specific + // conversion of an input string to an integral value. + // + // main entry point: + // + // extract_int<Radix, MinDigits, MaxDigits, Accumulate> + // ::f(first, last, n, count); + // + // The template parameter Radix represents the radix of the + // number contained in the parsed string. The template + // parameter MinDigits specifies the minimum digits to + // accept. The template parameter MaxDigits specifies the + // maximum digits to parse. A -1 value for MaxDigits will + // make it parse an arbitrarilly large number as long as the + // numeric type can hold it. Accumulate is either + // positive_accumulate<Radix> (default) for parsing positive + // numbers or negative_accumulate<Radix> otherwise. + // Checking is only performed when std::numeric_limits<T>:: + // is_specialized is true. Otherwise, there's no way to + // do the check. + // + // scan.first and scan.last are iterators as usual (i.e. + // first is mutable and is moved forward when a match is + // found), n is a variable that holds the number (passed by + // reference). The number of parsed characters is added to + // count (also passed by reference) + // + // NOTE: + // Returns a non-match, if the number to parse + // overflows (or underflows) the used type. + // + // BEWARE: + // the parameters 'n' and 'count' should be properly + // initialized before calling this function. + // + /////////////////////////////////////////////////////////////////////// +#if defined(BOOST_MSVC) +#pragma warning(push) +#pragma warning(disable:4127) //conditional expression is constant +#endif + + template <typename T, int Radix> + struct positive_accumulate + { + // Use this accumulator if number is positive + static bool add(T& n, T digit) + { + if (std::numeric_limits<T>::is_specialized) + { + static T const max = (std::numeric_limits<T>::max)(); + static T const max_div_radix = max/Radix; + + if (n > max_div_radix) + return false; + n *= Radix; + + if (n > max - digit) + return false; + n += digit; + + return true; + } + else + { + n *= Radix; + n += digit; + return true; + } + } + }; + + template <typename T, int Radix> + struct negative_accumulate + { + // Use this accumulator if number is negative + static bool add(T& n, T digit) + { + if (std::numeric_limits<T>::is_specialized) + { + typedef std::numeric_limits<T> num_limits; + static T const min = + (!num_limits::is_integer && num_limits::is_signed && num_limits::has_denorm) ? + -(num_limits::max)() : (num_limits::min)(); + static T const min_div_radix = min/Radix; + + if (n < min_div_radix) + return false; + n *= Radix; + + if (n < min + digit) + return false; + n -= digit; + + return true; + } + else + { + n *= Radix; + n -= digit; + return true; + } + } + }; + + template <int MaxDigits> + inline bool allow_more_digits(std::size_t i) + { + return i < MaxDigits; + } + + template <> + inline bool allow_more_digits<-1>(std::size_t) + { + return true; + } + + ////////////////////////////////// + template < + int Radix, unsigned MinDigits, int MaxDigits, + typename Accumulate + > + struct extract_int + { + template <typename ScannerT, typename T> + static bool + f(ScannerT& scan, T& n, std::size_t& count) + { + std::size_t i = 0; + T digit; + while( allow_more_digits<MaxDigits>(i) && !scan.at_end() && + radix_traits<Radix>::digit(*scan, digit) ) + { + if (!Accumulate::add(n, digit)) + return false; // Overflow + ++i, ++scan, ++count; + } + return i >= MinDigits; + } + }; + + /////////////////////////////////////////////////////////////////////// + // + // uint_parser_impl class + // + /////////////////////////////////////////////////////////////////////// + template < + typename T = unsigned, + int Radix = 10, + unsigned MinDigits = 1, + int MaxDigits = -1 + > + struct uint_parser_impl + : parser<uint_parser_impl<T, Radix, MinDigits, MaxDigits> > + { + typedef uint_parser_impl<T, Radix, MinDigits, MaxDigits> self_t; + + template <typename ScannerT> + struct result + { + typedef typename match_result<ScannerT, T>::type type; + }; + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + if (!scan.at_end()) + { + T n = 0; + std::size_t count = 0; + typename ScannerT::iterator_t save = scan.first; + if (extract_int<Radix, MinDigits, MaxDigits, + positive_accumulate<T, Radix> >::f(scan, n, count)) + { + return scan.create_match(count, n, save, scan.first); + } + // return no-match if number overflows + } + return scan.no_match(); + } + }; + + /////////////////////////////////////////////////////////////////////// + // + // int_parser_impl class + // + /////////////////////////////////////////////////////////////////////// + template < + typename T = unsigned, + int Radix = 10, + unsigned MinDigits = 1, + int MaxDigits = -1 + > + struct int_parser_impl + : parser<int_parser_impl<T, Radix, MinDigits, MaxDigits> > + { + typedef int_parser_impl<T, Radix, MinDigits, MaxDigits> self_t; + + template <typename ScannerT> + struct result + { + typedef typename match_result<ScannerT, T>::type type; + }; + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef extract_int<Radix, MinDigits, MaxDigits, + negative_accumulate<T, Radix> > extract_int_neg_t; + typedef extract_int<Radix, MinDigits, MaxDigits, + positive_accumulate<T, Radix> > extract_int_pos_t; + + if (!scan.at_end()) + { + T n = 0; + std::size_t count = 0; + typename ScannerT::iterator_t save = scan.first; + + bool hit = impl::extract_sign(scan, count); + + if (hit) + hit = extract_int_neg_t::f(scan, n, count); + else + hit = extract_int_pos_t::f(scan, n, count); + + if (hit) + return scan.create_match(count, n, save, scan.first); + else + scan.first = save; + // return no-match if number overflows or underflows + } + return scan.no_match(); + } + }; + + /////////////////////////////////////////////////////////////////////// + // + // real_parser_impl class + // + /////////////////////////////////////////////////////////////////////// + template <typename RT, typename T, typename RealPoliciesT> + struct real_parser_impl + { + typedef real_parser_impl<RT, T, RealPoliciesT> self_t; + + template <typename ScannerT> + RT parse_main(ScannerT const& scan) const + { + if (scan.at_end()) + return scan.no_match(); + typename ScannerT::iterator_t save = scan.first; + + typedef typename parser_result<sign_parser, ScannerT>::type + sign_match_t; + typedef typename parser_result<chlit<>, ScannerT>::type + exp_match_t; + + sign_match_t sign_match = RealPoliciesT::parse_sign(scan); + std::size_t count = sign_match ? sign_match.length() : 0; + bool neg = sign_match.has_valid_attribute() ? + sign_match.value() : false; + + RT n_match = RealPoliciesT::parse_n(scan); + T n = n_match.has_valid_attribute() ? + n_match.value() : T(0); + bool got_a_number = n_match; + exp_match_t e_hit; + + if (!got_a_number && !RealPoliciesT::allow_leading_dot) + return scan.no_match(); + else + count += n_match.length(); + + if (neg) + n = -n; + + if (RealPoliciesT::parse_dot(scan)) + { + // We got the decimal point. Now we will try to parse + // the fraction if it is there. If not, it defaults + // to zero (0) only if we already got a number. + + if (RT hit = RealPoliciesT::parse_frac_n(scan)) + { +#if !defined(BOOST_NO_STDC_NAMESPACE) + using namespace std; // allow for ADL to find pow() +#endif + hit.value(hit.value() + * pow(T(10), T(-hit.length()))); + if (neg) + n -= hit.value(); + else + n += hit.value(); + count += hit.length() + 1; + + } + + else if (!got_a_number || + !RealPoliciesT::allow_trailing_dot) + return scan.no_match(); + + e_hit = RealPoliciesT::parse_exp(scan); + } + else + { + // We have reached a point where we + // still haven't seen a number at all. + // We return early with a no-match. + if (!got_a_number) + return scan.no_match(); + + // If we must expect a dot and we didn't see + // an exponent, return early with a no-match. + e_hit = RealPoliciesT::parse_exp(scan); + if (RealPoliciesT::expect_dot && !e_hit) + return scan.no_match(); + } + + if (e_hit) + { + // We got the exponent prefix. Now we will try to parse the + // actual exponent. It is an error if it is not there. + if (RT e_n_hit = RealPoliciesT::parse_exp_n(scan)) + { +#if !defined(BOOST_NO_STDC_NAMESPACE) + using namespace std; // allow for ADL to find pow() +#endif + n *= pow(T(10), T(e_n_hit.value())); + count += e_n_hit.length() + e_hit.length(); + } + else + { + // Oops, no exponent, return a no-match + return scan.no_match(); + } + } + + return scan.create_match(count, n, save, scan.first); + } + + template <typename ScannerT> + static RT parse(ScannerT const& scan) + { + static self_t this_; + return impl::implicit_lexeme_parse<RT>(this_, scan, scan); + } + }; + +#if defined(BOOST_MSVC) +#pragma warning(pop) +#endif + + } // namespace impl + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#endif diff --git a/boost/spirit/home/classic/core/primitives/impl/primitives.ipp b/boost/spirit/home/classic/core/primitives/impl/primitives.ipp new file mode 100644 index 0000000000..152e5b11be --- /dev/null +++ b/boost/spirit/home/classic/core/primitives/impl/primitives.ipp @@ -0,0 +1,476 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2003 Martin Wille + 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) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_PRIMITIVES_IPP) +#define BOOST_SPIRIT_PRIMITIVES_IPP + +// This should eventually go to a config file. +#if defined(__GNUC__) && (__GNUC__ < 3) && !defined(_STLPORT_VERSION) +# ifndef BOOST_SPIRIT_NO_CHAR_TRAITS +# define BOOST_SPIRIT_NO_CHAR_TRAITS +# endif +#endif + +#include <cctype> +#if !defined(BOOST_NO_CWCTYPE) +#include <cwctype> +#endif + +#ifndef BOOST_SPIRIT_NO_CHAR_TRAITS +# include <string> // char_traits +#endif + +#if defined(BOOST_MSVC) +# pragma warning (push) +# pragma warning(disable:4800) +#endif + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + template <typename DrivedT> struct char_parser; + + namespace impl + { + template <typename IteratorT> + inline IteratorT + get_last(IteratorT first) + { + while (*first) + first++; + return first; + } + + template< + typename RT, + typename IteratorT, + typename ScannerT> + inline RT + string_parser_parse( + IteratorT str_first, + IteratorT str_last, + ScannerT& scan) + { + typedef typename ScannerT::iterator_t iterator_t; + iterator_t saved = scan.first; + std::size_t slen = str_last - str_first; + + while (str_first != str_last) + { + if (scan.at_end() || (*str_first != *scan)) + return scan.no_match(); + ++str_first; + ++scan; + } + + return scan.create_match(slen, nil_t(), saved, scan.first); + } + + /////////////////////////////////////////////////////////////////////////// + // + // Conversion from char_type to int_type + // + /////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_SPIRIT_NO_CHAR_TRAITS +# define BOOST_SPIRIT_CHAR_TRAITS_NAMESPACE std +#else + + template <typename CharT> + struct char_traits + { + typedef CharT int_type; + typedef CharT char_type; + }; + + template<> + struct char_traits<char> + { + typedef int int_type; + typedef char char_type; + + static char_type + to_char_type(int_type c) + { + return static_cast<char_type>(c); + } + + static int + to_int_type(char c) + { + return static_cast<unsigned char>(c); + } + }; + + template<> + struct char_traits<unsigned char> + { + typedef int int_type; + typedef unsigned char char_type; + + static char_type + to_char_type(int_type c) + { + return static_cast<char_type>(c); + } + + static int + to_int_type(unsigned char c) + { + return c; + } + }; + +# define BOOST_SPIRIT_CHAR_TRAITS_NAMESPACE impl +# ifndef BOOST_NO_CWCTYPE + + template<> + struct char_traits<wchar_t> + { + typedef wint_t int_type; + typedef wchar_t char_type; + + static char_type + to_char_type(int_type c) + { + return static_cast<char_type>(c); + } + + static wint_t + to_int_type(wchar_t c) + { + return c; + } + }; + +# endif +#endif // BOOST_SPIRIT_NO_CHAR_TRAITS + + // Use char_traits for char and wchar_t only, as these are the only + // specializations provided in the standard. Other types are on their + // own. + // + // For UDT, one may override: + // + // isalnum + // isalpha + // iscntrl + // isdigit + // isgraph + // islower + // isprint + // ispunct + // isspace + // isupper + // isxdigit + // isblank + // isupper + // tolower + // toupper + // + // in a namespace suitable for Argument Dependent lookup or in + // namespace std (disallowed by the standard). + + template <typename CharT> + struct char_type_char_traits_helper + { + typedef CharT char_type; + typedef typename BOOST_SPIRIT_CHAR_TRAITS_NAMESPACE + ::char_traits<CharT>::int_type int_type; + + static int_type to_int_type(CharT c) + { + return BOOST_SPIRIT_CHAR_TRAITS_NAMESPACE + ::char_traits<CharT>::to_int_type(c); + } + + static char_type to_char_type(int_type i) + { + return BOOST_SPIRIT_CHAR_TRAITS_NAMESPACE + ::char_traits<CharT>::to_char_type(i); + } + }; + + template <typename CharT> + struct char_traits_helper + { + typedef CharT char_type; + typedef CharT int_type; + + static CharT & to_int_type(CharT & c) + { + return c; + } + + static CharT & to_char_type(CharT & c) + { + return c; + } + }; + + template <> + struct char_traits_helper<char> + : char_type_char_traits_helper<char> + { + }; + +#if !defined(BOOST_NO_CWCTYPE) + + template <> + struct char_traits_helper<wchar_t> + : char_type_char_traits_helper<wchar_t> + { + }; + +#endif + + template <typename CharT> + inline typename char_traits_helper<CharT>::int_type + to_int_type(CharT c) + { + return char_traits_helper<CharT>::to_int_type(c); + } + + template <typename CharT> + inline CharT + to_char_type(typename char_traits_helper<CharT>::int_type c) + { + return char_traits_helper<CharT>::to_char_type(c); + } + + /////////////////////////////////////////////////////////////////////// + // + // Convenience functions + // + /////////////////////////////////////////////////////////////////////// + + template <typename CharT> + inline bool + isalnum_(CharT c) + { + using namespace std; + return isalnum(to_int_type(c)) ? true : false; + } + + template <typename CharT> + inline bool + isalpha_(CharT c) + { + using namespace std; + return isalpha(to_int_type(c)) ? true : false; + } + + template <typename CharT> + inline bool + iscntrl_(CharT c) + { + using namespace std; + return iscntrl(to_int_type(c)) ? true : false; + } + + template <typename CharT> + inline bool + isdigit_(CharT c) + { + using namespace std; + return isdigit(to_int_type(c)) ? true : false; + } + + template <typename CharT> + inline bool + isgraph_(CharT c) + { + using namespace std; + return isgraph(to_int_type(c)) ? true : false; + } + + template <typename CharT> + inline bool + islower_(CharT c) + { + using namespace std; + return islower(to_int_type(c)) ? true : false; + } + + template <typename CharT> + inline bool + isprint_(CharT c) + { + using namespace std; + return isprint(to_int_type(c)) ? true : false; + } + + template <typename CharT> + inline bool + ispunct_(CharT c) + { + using namespace std; + return ispunct(to_int_type(c)) ? true : false; + } + + template <typename CharT> + inline bool + isspace_(CharT c) + { + using namespace std; + return isspace(to_int_type(c)) ? true : false; + } + + template <typename CharT> + inline bool + isupper_(CharT c) + { + using namespace std; + return isupper(to_int_type(c)) ? true : false; + } + + template <typename CharT> + inline bool + isxdigit_(CharT c) + { + using namespace std; + return isxdigit(to_int_type(c)) ? true : false; + } + + template <typename CharT> + inline bool + isblank_(CharT c) + { + return (c == ' ' || c == '\t'); + } + + template <typename CharT> + inline CharT + tolower_(CharT c) + { + using namespace std; + return to_char_type<CharT>(tolower(to_int_type(c))); + } + + template <typename CharT> + inline CharT + toupper_(CharT c) + { + using namespace std; + return to_char_type<CharT>(toupper(to_int_type(c))); + } + +#if !defined(BOOST_NO_CWCTYPE) + + inline bool + isalnum_(wchar_t c) + { + using namespace std; + return iswalnum(to_int_type(c)) ? true : false; + } + + inline bool + isalpha_(wchar_t c) + { + using namespace std; + return iswalpha(to_int_type(c)) ? true : false; + } + + inline bool + iscntrl_(wchar_t c) + { + using namespace std; + return iswcntrl(to_int_type(c)) ? true : false; + } + + inline bool + isdigit_(wchar_t c) + { + using namespace std; + return iswdigit(to_int_type(c)) ? true : false; + } + + inline bool + isgraph_(wchar_t c) + { + using namespace std; + return iswgraph(to_int_type(c)) ? true : false; + } + + inline bool + islower_(wchar_t c) + { + using namespace std; + return iswlower(to_int_type(c)) ? true : false; + } + + inline bool + isprint_(wchar_t c) + { + using namespace std; + return iswprint(to_int_type(c)) ? true : false; + } + + inline bool + ispunct_(wchar_t c) + { + using namespace std; + return iswpunct(to_int_type(c)) ? true : false; + } + + inline bool + isspace_(wchar_t c) + { + using namespace std; + return iswspace(to_int_type(c)) ? true : false; + } + + inline bool + isupper_(wchar_t c) + { + using namespace std; + return iswupper(to_int_type(c)) ? true : false; + } + + inline bool + isxdigit_(wchar_t c) + { + using namespace std; + return iswxdigit(to_int_type(c)) ? true : false; + } + + inline bool + isblank_(wchar_t c) + { + return (c == L' ' || c == L'\t'); + } + + inline wchar_t + tolower_(wchar_t c) + { + using namespace std; + return to_char_type<wchar_t>(towlower(to_int_type(c))); + } + + inline wchar_t + toupper_(wchar_t c) + { + using namespace std; + return to_char_type<wchar_t>(towupper(to_int_type(c))); + } + +#endif // !defined(BOOST_NO_CWCTYPE) + +} + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit::impl + +#ifdef BOOST_MSVC +#pragma warning (pop) +#endif + +#endif diff --git a/boost/spirit/home/classic/core/primitives/numerics.hpp b/boost/spirit/home/classic/core/primitives/numerics.hpp new file mode 100644 index 0000000000..20ea0911a1 --- /dev/null +++ b/boost/spirit/home/classic/core/primitives/numerics.hpp @@ -0,0 +1,289 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001-2003 Hartmut Kaiser + 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_NUMERICS_HPP +#define BOOST_SPIRIT_NUMERICS_HPP + +#include <boost/config.hpp> +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/core/composite/directives.hpp> + +#include <boost/spirit/home/classic/core/primitives/numerics_fwd.hpp> +#include <boost/spirit/home/classic/core/primitives/impl/numerics.ipp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // uint_parser class + // + /////////////////////////////////////////////////////////////////////////// + template < + typename T, + int Radix, + unsigned MinDigits, + int MaxDigits + > + struct uint_parser : parser<uint_parser<T, Radix, MinDigits, MaxDigits> > + { + typedef uint_parser<T, Radix, MinDigits, MaxDigits> self_t; + + template <typename ScannerT> + struct result + { + typedef typename match_result<ScannerT, T>::type type; + }; + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef impl::uint_parser_impl<T, Radix, MinDigits, MaxDigits> impl_t; + typedef typename parser_result<impl_t, ScannerT>::type result_t; + return impl::contiguous_parser_parse<result_t>(impl_t(), scan, scan); + } + }; + + /////////////////////////////////////////////////////////////////////////// + // + // int_parser class + // + /////////////////////////////////////////////////////////////////////////// + template < + typename T, + int Radix, + unsigned MinDigits, + int MaxDigits + > + struct int_parser : parser<int_parser<T, Radix, MinDigits, MaxDigits> > + { + typedef int_parser<T, Radix, MinDigits, MaxDigits> self_t; + + template <typename ScannerT> + struct result + { + typedef typename match_result<ScannerT, T>::type type; + }; + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef impl::int_parser_impl<T, Radix, MinDigits, MaxDigits> impl_t; + typedef typename parser_result<impl_t, ScannerT>::type result_t; + return impl::contiguous_parser_parse<result_t>(impl_t(), scan, scan); + } + }; + + /////////////////////////////////////////////////////////////////////////// + // + // uint_parser/int_parser instantiations + // + /////////////////////////////////////////////////////////////////////////// + int_parser<int> const + int_p = int_parser<int>(); + + uint_parser<unsigned> const + uint_p = uint_parser<unsigned>(); + + uint_parser<unsigned, 2> const + bin_p = uint_parser<unsigned, 2>(); + + uint_parser<unsigned, 8> const + oct_p = uint_parser<unsigned, 8>(); + + uint_parser<unsigned, 16> const + hex_p = uint_parser<unsigned, 16>(); + + /////////////////////////////////////////////////////////////////////////// + // + // sign_parser class + // + /////////////////////////////////////////////////////////////////////////// + namespace impl + { + // Utility to extract the prefix sign ('-' | '+') + template <typename ScannerT> + bool extract_sign(ScannerT const& scan, std::size_t& count); + } + + struct sign_parser : public parser<sign_parser> + { + typedef sign_parser self_t; + + template <typename ScannerT> + struct result + { + typedef typename match_result<ScannerT, bool>::type type; + }; + + sign_parser() {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + if (!scan.at_end()) + { + std::size_t length; + typename ScannerT::iterator_t save(scan.first); + bool neg = impl::extract_sign(scan, length); + if (length) + return scan.create_match(1, neg, save, scan.first); + } + return scan.no_match(); + } + }; + + sign_parser const sign_p = sign_parser(); + + /////////////////////////////////////////////////////////////////////////// + // + // default real number policies + // + /////////////////////////////////////////////////////////////////////////// + template <typename T> + struct ureal_parser_policies + { + // trailing dot policy suggested suggested by Gustavo Guerra + BOOST_STATIC_CONSTANT(bool, allow_leading_dot = true); + BOOST_STATIC_CONSTANT(bool, allow_trailing_dot = true); + BOOST_STATIC_CONSTANT(bool, expect_dot = false); + + typedef uint_parser<T, 10, 1, -1> uint_parser_t; + typedef int_parser<T, 10, 1, -1> int_parser_t; + + template <typename ScannerT> + static typename match_result<ScannerT, nil_t>::type + parse_sign(ScannerT& scan) + { + return scan.no_match(); + } + + template <typename ScannerT> + static typename parser_result<uint_parser_t, ScannerT>::type + parse_n(ScannerT& scan) + { + return uint_parser_t().parse(scan); + } + + template <typename ScannerT> + static typename parser_result<chlit<>, ScannerT>::type + parse_dot(ScannerT& scan) + { + return ch_p('.').parse(scan); + } + + template <typename ScannerT> + static typename parser_result<uint_parser_t, ScannerT>::type + parse_frac_n(ScannerT& scan) + { + return uint_parser_t().parse(scan); + } + + template <typename ScannerT> + static typename parser_result<chlit<>, ScannerT>::type + parse_exp(ScannerT& scan) + { + return as_lower_d['e'].parse(scan); + } + + template <typename ScannerT> + static typename parser_result<int_parser_t, ScannerT>::type + parse_exp_n(ScannerT& scan) + { + return int_parser_t().parse(scan); + } + }; + + template <typename T> + struct real_parser_policies : public ureal_parser_policies<T> + { + template <typename ScannerT> + static typename parser_result<sign_parser, ScannerT>::type + parse_sign(ScannerT& scan) + { + return sign_p.parse(scan); + } + }; + + /////////////////////////////////////////////////////////////////////////// + // + // real_parser class + // + /////////////////////////////////////////////////////////////////////////// + template < + typename T, + typename RealPoliciesT + > + struct real_parser + : public parser<real_parser<T, RealPoliciesT> > + { + typedef real_parser<T, RealPoliciesT> self_t; + + template <typename ScannerT> + struct result + { + typedef typename match_result<ScannerT, T>::type type; + }; + + real_parser() {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename parser_result<self_t, ScannerT>::type result_t; + return impl::real_parser_impl<result_t, T, RealPoliciesT>::parse(scan); + } + }; + + /////////////////////////////////////////////////////////////////////////// + // + // real_parser instantiations + // + /////////////////////////////////////////////////////////////////////////// + real_parser<double, ureal_parser_policies<double> > const + ureal_p = real_parser<double, ureal_parser_policies<double> >(); + + real_parser<double, real_parser_policies<double> > const + real_p = real_parser<double, real_parser_policies<double> >(); + + /////////////////////////////////////////////////////////////////////////// + // + // strict reals (do not allow plain integers (no decimal point)) + // + /////////////////////////////////////////////////////////////////////////// + template <typename T> + struct strict_ureal_parser_policies : public ureal_parser_policies<T> + { + BOOST_STATIC_CONSTANT(bool, expect_dot = true); + }; + + template <typename T> + struct strict_real_parser_policies : public real_parser_policies<T> + { + BOOST_STATIC_CONSTANT(bool, expect_dot = true); + }; + + real_parser<double, strict_ureal_parser_policies<double> > const + strict_ureal_p + = real_parser<double, strict_ureal_parser_policies<double> >(); + + real_parser<double, strict_real_parser_policies<double> > const + strict_real_p + = real_parser<double, strict_real_parser_policies<double> >(); + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif diff --git a/boost/spirit/home/classic/core/primitives/numerics_fwd.hpp b/boost/spirit/home/classic/core/primitives/numerics_fwd.hpp new file mode 100644 index 0000000000..b0f20d9aaa --- /dev/null +++ b/boost/spirit/home/classic/core/primitives/numerics_fwd.hpp @@ -0,0 +1,88 @@ +/*============================================================================= + Copyright (C) 2006 Tobias Schwinger + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_NUMERICS_FWD_HPP) +# define BOOST_SPIRIT_NUMERICS_FWD_HPP + +#include <boost/spirit/home/classic/namespace.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // uint_parser class + // + /////////////////////////////////////////////////////////////////////////// + template < + typename T = unsigned, + int Radix = 10, + unsigned MinDigits = 1, + int MaxDigits = -1 + > + struct uint_parser; + + /////////////////////////////////////////////////////////////////////////// + // + // int_parser class + // + /////////////////////////////////////////////////////////////////////////// + template < + typename T = unsigned, + int Radix = 10, + unsigned MinDigits = 1, + int MaxDigits = -1 + > + struct int_parser; + + /////////////////////////////////////////////////////////////////////////// + // + // sign_parser class + // + /////////////////////////////////////////////////////////////////////////// + struct sign_parser; + + /////////////////////////////////////////////////////////////////////////// + // + // default real number policies + // + /////////////////////////////////////////////////////////////////////////// + template <typename T> + struct ureal_parser_policies; + + template <typename T> + struct real_parser_policies; + + /////////////////////////////////////////////////////////////////////////// + // + // real_parser class + // + /////////////////////////////////////////////////////////////////////////// + template < + typename T = double, + typename RealPoliciesT = ureal_parser_policies<T> + > + struct real_parser; + + /////////////////////////////////////////////////////////////////////////// + // + // strict reals (do not allow plain integers (no decimal point)) + // + /////////////////////////////////////////////////////////////////////////// + template <typename T> + struct strict_ureal_parser_policies; + + template <typename T> + struct strict_real_parser_policies; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + diff --git a/boost/spirit/home/classic/core/primitives/primitives.hpp b/boost/spirit/home/classic/core/primitives/primitives.hpp new file mode 100644 index 0000000000..d89585b102 --- /dev/null +++ b/boost/spirit/home/classic/core/primitives/primitives.hpp @@ -0,0 +1,654 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2003 Martin Wille + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_PRIMITIVES_HPP) +#define BOOST_SPIRIT_PRIMITIVES_HPP + +#include <boost/ref.hpp> +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/assert.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/core/composite/impl/directives.ipp> +#include <boost/spirit/home/classic/core/primitives/impl/primitives.ipp> + +#ifdef BOOST_MSVC +#pragma warning (push) +#pragma warning(disable : 4512) +#endif + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // char_parser class + // + /////////////////////////////////////////////////////////////////////////// + template <typename DerivedT> + struct char_parser : public parser<DerivedT> + { + typedef DerivedT self_t; + template <typename ScannerT> + struct result + { + typedef typename match_result< + ScannerT, + typename ScannerT::value_t + >::type type; + }; + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename parser_result<self_t, ScannerT>::type result_t; + typedef typename ScannerT::value_t value_t; + typedef typename ScannerT::iterator_t iterator_t; + + if (!scan.at_end()) + { + value_t ch = *scan; + if (this->derived().test(ch)) + { + iterator_t save(scan.first); + ++scan.first; + return scan.create_match(1, ch, save, scan.first); + } + } + return scan.no_match(); + } + }; + + /////////////////////////////////////////////////////////////////////////// + // + // negation of char_parsers + // + /////////////////////////////////////////////////////////////////////////// + template <typename PositiveT> + struct negated_char_parser + : public char_parser<negated_char_parser<PositiveT> > + { + typedef negated_char_parser<PositiveT> self_t; + typedef PositiveT positive_t; + + negated_char_parser(positive_t const& p) + : positive(p.derived()) {} + + template <typename T> + bool test(T ch) const + { + return !positive.test(ch); + } + + positive_t const positive; + }; + + template <typename ParserT> + inline negated_char_parser<ParserT> + operator~(char_parser<ParserT> const& p) + { + return negated_char_parser<ParserT>(p.derived()); + } + + template <typename ParserT> + inline ParserT + operator~(negated_char_parser<ParserT> const& n) + { + return n.positive; + } + + /////////////////////////////////////////////////////////////////////////// + // + // chlit class + // + /////////////////////////////////////////////////////////////////////////// + template <typename CharT = char> + struct chlit : public char_parser<chlit<CharT> > + { + chlit(CharT ch_) + : ch(ch_) {} + + template <typename T> + bool test(T ch_) const + { + return ch_ == ch; + } + + CharT ch; + }; + + template <typename CharT> + inline chlit<CharT> + ch_p(CharT ch) + { + return chlit<CharT>(ch); + } + + // This should take care of ch_p("a") "bugs" + template <typename CharT, std::size_t N> + inline chlit<CharT> + ch_p(CharT const (& str)[N]) + { + // ch_p's argument should be a single character or a null-terminated + // string with a single character + BOOST_STATIC_ASSERT(N < 3); + return chlit<CharT>(str[0]); + } + + /////////////////////////////////////////////////////////////////////////// + // + // range class + // + /////////////////////////////////////////////////////////////////////////// + template <typename CharT = char> + struct range : public char_parser<range<CharT> > + { + range(CharT first_, CharT last_) + : first(first_), last(last_) + { + BOOST_SPIRIT_ASSERT(!(last < first)); + } + + template <typename T> + bool test(T ch) const + { + return !(CharT(ch) < first) && !(last < CharT(ch)); + } + + CharT first; + CharT last; + }; + + template <typename CharT> + inline range<CharT> + range_p(CharT first, CharT last) + { + return range<CharT>(first, last); + } + + /////////////////////////////////////////////////////////////////////////// + // + // chseq class + // + /////////////////////////////////////////////////////////////////////////// + template <typename IteratorT = char const*> + class chseq : public parser<chseq<IteratorT> > + { + public: + + typedef chseq<IteratorT> self_t; + + chseq(IteratorT first_, IteratorT last_) + : first(first_), last(last_) {} + + chseq(IteratorT first_) + : first(first_), last(impl::get_last(first_)) {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename boost::unwrap_reference<IteratorT>::type striter_t; + typedef typename parser_result<self_t, ScannerT>::type result_t; + return impl::string_parser_parse<result_t>( + striter_t(first), + striter_t(last), + scan); + } + + private: + + IteratorT first; + IteratorT last; + }; + + template <typename CharT> + inline chseq<CharT const*> + chseq_p(CharT const* str) + { + return chseq<CharT const*>(str); + } + + template <typename IteratorT> + inline chseq<IteratorT> + chseq_p(IteratorT first, IteratorT last) + { + return chseq<IteratorT>(first, last); + } + + /////////////////////////////////////////////////////////////////////////// + // + // strlit class + // + /////////////////////////////////////////////////////////////////////////// + template <typename IteratorT = char const*> + class strlit : public parser<strlit<IteratorT> > + { + public: + + typedef strlit<IteratorT> self_t; + + strlit(IteratorT first, IteratorT last) + : seq(first, last) {} + + strlit(IteratorT first) + : seq(first) {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename parser_result<self_t, ScannerT>::type result_t; + return impl::contiguous_parser_parse<result_t> + (seq, scan, scan); + } + + private: + + chseq<IteratorT> seq; + }; + + template <typename CharT> + inline strlit<CharT const*> + str_p(CharT const* str) + { + return strlit<CharT const*>(str); + } + + template <typename CharT> + inline strlit<CharT *> + str_p(CharT * str) + { + return strlit<CharT *>(str); + } + + template <typename IteratorT> + inline strlit<IteratorT> + str_p(IteratorT first, IteratorT last) + { + return strlit<IteratorT>(first, last); + } + + // This should take care of str_p('a') "bugs" + template <typename CharT> + inline chlit<CharT> + str_p(CharT ch) + { + return chlit<CharT>(ch); + } + + /////////////////////////////////////////////////////////////////////////// + // + // nothing_parser class + // + /////////////////////////////////////////////////////////////////////////// + struct nothing_parser : public parser<nothing_parser> + { + typedef nothing_parser self_t; + + nothing_parser() {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + return scan.no_match(); + } + }; + + nothing_parser const nothing_p = nothing_parser(); + + /////////////////////////////////////////////////////////////////////////// + // + // anychar_parser class + // + /////////////////////////////////////////////////////////////////////////// + struct anychar_parser : public char_parser<anychar_parser> + { + typedef anychar_parser self_t; + + anychar_parser() {} + + template <typename CharT> + bool test(CharT) const + { + return true; + } + }; + + anychar_parser const anychar_p = anychar_parser(); + + inline nothing_parser + operator~(anychar_parser) + { + return nothing_p; + } + + /////////////////////////////////////////////////////////////////////////// + // + // alnum_parser class + // + /////////////////////////////////////////////////////////////////////////// + struct alnum_parser : public char_parser<alnum_parser> + { + typedef alnum_parser self_t; + + alnum_parser() {} + + template <typename CharT> + bool test(CharT ch) const + { + return impl::isalnum_(ch); + } + }; + + alnum_parser const alnum_p = alnum_parser(); + + /////////////////////////////////////////////////////////////////////////// + // + // alpha_parser class + // + /////////////////////////////////////////////////////////////////////////// + struct alpha_parser : public char_parser<alpha_parser> + { + typedef alpha_parser self_t; + + alpha_parser() {} + + template <typename CharT> + bool test(CharT ch) const + { + return impl::isalpha_(ch); + } + }; + + alpha_parser const alpha_p = alpha_parser(); + + /////////////////////////////////////////////////////////////////////////// + // + // cntrl_parser class + // + /////////////////////////////////////////////////////////////////////////// + struct cntrl_parser : public char_parser<cntrl_parser> + { + typedef cntrl_parser self_t; + + cntrl_parser() {} + + template <typename CharT> + bool test(CharT ch) const + { + return impl::iscntrl_(ch); + } + }; + + cntrl_parser const cntrl_p = cntrl_parser(); + + /////////////////////////////////////////////////////////////////////////// + // + // digit_parser class + // + /////////////////////////////////////////////////////////////////////////// + struct digit_parser : public char_parser<digit_parser> + { + typedef digit_parser self_t; + + digit_parser() {} + + template <typename CharT> + bool test(CharT ch) const + { + return impl::isdigit_(ch); + } + }; + + digit_parser const digit_p = digit_parser(); + + /////////////////////////////////////////////////////////////////////////// + // + // graph_parser class + // + /////////////////////////////////////////////////////////////////////////// + struct graph_parser : public char_parser<graph_parser> + { + typedef graph_parser self_t; + + graph_parser() {} + + template <typename CharT> + bool test(CharT ch) const + { + return impl::isgraph_(ch); + } + }; + + graph_parser const graph_p = graph_parser(); + + /////////////////////////////////////////////////////////////////////////// + // + // lower_parser class + // + /////////////////////////////////////////////////////////////////////////// + struct lower_parser : public char_parser<lower_parser> + { + typedef lower_parser self_t; + + lower_parser() {} + + template <typename CharT> + bool test(CharT ch) const + { + return impl::islower_(ch); + } + }; + + lower_parser const lower_p = lower_parser(); + + /////////////////////////////////////////////////////////////////////////// + // + // print_parser class + // + /////////////////////////////////////////////////////////////////////////// + struct print_parser : public char_parser<print_parser> + { + typedef print_parser self_t; + + print_parser() {} + + template <typename CharT> + bool test(CharT ch) const + { + return impl::isprint_(ch); + } + }; + + print_parser const print_p = print_parser(); + + /////////////////////////////////////////////////////////////////////////// + // + // punct_parser class + // + /////////////////////////////////////////////////////////////////////////// + struct punct_parser : public char_parser<punct_parser> + { + typedef punct_parser self_t; + + punct_parser() {} + + template <typename CharT> + bool test(CharT ch) const + { + return impl::ispunct_(ch); + } + }; + + punct_parser const punct_p = punct_parser(); + + /////////////////////////////////////////////////////////////////////////// + // + // blank_parser class + // + /////////////////////////////////////////////////////////////////////////// + struct blank_parser : public char_parser<blank_parser> + { + typedef blank_parser self_t; + + blank_parser() {} + + template <typename CharT> + bool test(CharT ch) const + { + return impl::isblank_(ch); + } + }; + + blank_parser const blank_p = blank_parser(); + + /////////////////////////////////////////////////////////////////////////// + // + // space_parser class + // + /////////////////////////////////////////////////////////////////////////// + struct space_parser : public char_parser<space_parser> + { + typedef space_parser self_t; + + space_parser() {} + + template <typename CharT> + bool test(CharT ch) const + { + return impl::isspace_(ch); + } + }; + + space_parser const space_p = space_parser(); + + /////////////////////////////////////////////////////////////////////////// + // + // upper_parser class + // + /////////////////////////////////////////////////////////////////////////// + struct upper_parser : public char_parser<upper_parser> + { + typedef upper_parser self_t; + + upper_parser() {} + + template <typename CharT> + bool test(CharT ch) const + { + return impl::isupper_(ch); + } + }; + + upper_parser const upper_p = upper_parser(); + + /////////////////////////////////////////////////////////////////////////// + // + // xdigit_parser class + // + /////////////////////////////////////////////////////////////////////////// + struct xdigit_parser : public char_parser<xdigit_parser> + { + typedef xdigit_parser self_t; + + xdigit_parser() {} + + template <typename CharT> + bool test(CharT ch) const + { + return impl::isxdigit_(ch); + } + }; + + xdigit_parser const xdigit_p = xdigit_parser(); + + /////////////////////////////////////////////////////////////////////////// + // + // eol_parser class (contributed by Martin Wille) + // + /////////////////////////////////////////////////////////////////////////// + struct eol_parser : public parser<eol_parser> + { + typedef eol_parser self_t; + + eol_parser() {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typename ScannerT::iterator_t save = scan.first; + std::size_t len = 0; + + if (!scan.at_end() && *scan == '\r') // CR + { + ++scan.first; + ++len; + } + + // Don't call skipper here + if (scan.first != scan.last && *scan == '\n') // LF + { + ++scan.first; + ++len; + } + + if (len) + return scan.create_match(len, nil_t(), save, scan.first); + return scan.no_match(); + } + }; + + eol_parser const eol_p = eol_parser(); + + /////////////////////////////////////////////////////////////////////////// + // + // end_parser class (suggested by Markus Schoepflin) + // + /////////////////////////////////////////////////////////////////////////// + struct end_parser : public parser<end_parser> + { + typedef end_parser self_t; + + end_parser() {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + if (scan.at_end()) + return scan.empty_match(); + return scan.no_match(); + } + }; + + end_parser const end_p = end_parser(); + + /////////////////////////////////////////////////////////////////////////// + // + // the pizza_p parser :-) + // + /////////////////////////////////////////////////////////////////////////// + inline strlit<char const*> const + pizza_p(char const* your_favorite_pizza) + { + return your_favorite_pizza; + } + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#ifdef BOOST_MSVC +#pragma warning (pop) +#endif + +#endif diff --git a/boost/spirit/home/classic/core/safe_bool.hpp b/boost/spirit/home/classic/core/safe_bool.hpp new file mode 100644 index 0000000000..73b6e7b64b --- /dev/null +++ b/boost/spirit/home/classic/core/safe_bool.hpp @@ -0,0 +1,64 @@ +/*============================================================================= + Copyright (c) 2003 Joel de Guzman + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_SAFE_BOOL_HPP) +#define BOOST_SPIRIT_SAFE_BOOL_HPP + +#include <boost/config.hpp> +#include <boost/detail/workaround.hpp> +#include <boost/spirit/home/classic/namespace.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + namespace impl + { + template <typename T> + struct no_base {}; + + template <typename T> + struct safe_bool_impl + { +#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) + void stub(T*) {}; + typedef void (safe_bool_impl::*type)(T*); +#else + typedef T* TP; // workaround to make parsing easier + TP stub; + typedef TP safe_bool_impl::*type; +#endif + }; + } + + template <typename DerivedT, typename BaseT = impl::no_base<DerivedT> > + struct safe_bool : BaseT + { + private: + typedef impl::safe_bool_impl<DerivedT> impl_t; + typedef typename impl_t::type bool_type; + + public: + operator bool_type() const + { + return static_cast<const DerivedT*>(this)->operator_bool() ? + &impl_t::stub : 0; + } + + operator bool_type() + { + return static_cast<DerivedT*>(this)->operator_bool() ? + &impl_t::stub : 0; + } + }; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} + +#endif + diff --git a/boost/spirit/home/classic/core/scanner/impl/skipper.ipp b/boost/spirit/home/classic/core/scanner/impl/skipper.ipp new file mode 100644 index 0000000000..fab74bde3a --- /dev/null +++ b/boost/spirit/home/classic/core/scanner/impl/skipper.ipp @@ -0,0 +1,181 @@ +/*============================================================================= + Copyright (c) 1998-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) +============================================================================*/ +#if !defined(BOOST_SPIRIT_SKIPPER_IPP) +#define BOOST_SPIRIT_SKIPPER_IPP + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + struct space_parser; + template <typename BaseT> + struct no_skipper_iteration_policy; + + namespace impl + { + template <typename ST, typename ScannerT, typename BaseT> + inline void + skipper_skip( + ST const& s, + ScannerT const& scan, + skipper_iteration_policy<BaseT> const&) + { + typedef scanner_policies< + no_skipper_iteration_policy< + BOOST_DEDUCED_TYPENAME ScannerT::iteration_policy_t>, + BOOST_DEDUCED_TYPENAME ScannerT::match_policy_t, + BOOST_DEDUCED_TYPENAME ScannerT::action_policy_t + > policies_t; + + scanner<BOOST_DEDUCED_TYPENAME ScannerT::iterator_t, policies_t> + scan2(scan.first, scan.last, policies_t(scan)); + typedef typename ScannerT::iterator_t iterator_t; + + for (;;) + { + iterator_t save = scan.first; + if (!s.parse(scan2)) + { + scan.first = save; + break; + } + } + } + + template <typename ST, typename ScannerT, typename BaseT> + inline void + skipper_skip( + ST const& s, + ScannerT const& scan, + no_skipper_iteration_policy<BaseT> const&) + { + for (;;) + { + typedef typename ScannerT::iterator_t iterator_t; + iterator_t save = scan.first; + if (!s.parse(scan)) + { + scan.first = save; + break; + } + } + } + + template <typename ST, typename ScannerT> + inline void + skipper_skip( + ST const& s, + ScannerT const& scan, + iteration_policy const&) + { + for (;;) + { + typedef typename ScannerT::iterator_t iterator_t; + iterator_t save = scan.first; + if (!s.parse(scan)) + { + scan.first = save; + break; + } + } + } + + template <typename SkipT> + struct phrase_parser + { + template <typename IteratorT, typename ParserT> + static parse_info<IteratorT> + parse( + IteratorT const& first_, + IteratorT const& last, + ParserT const& p, + SkipT const& skip) + { + typedef skip_parser_iteration_policy<SkipT> iter_policy_t; + typedef scanner_policies<iter_policy_t> scanner_policies_t; + typedef scanner<IteratorT, scanner_policies_t> scanner_t; + + iter_policy_t iter_policy(skip); + scanner_policies_t policies(iter_policy); + IteratorT first = first_; + scanner_t scan(first, last, policies); + match<nil_t> hit = p.parse(scan); + return parse_info<IteratorT>( + first, hit, hit && (first == last), + hit.length()); + } + }; + + template <> + struct phrase_parser<space_parser> + { + template <typename IteratorT, typename ParserT> + static parse_info<IteratorT> + parse( + IteratorT const& first_, + IteratorT const& last, + ParserT const& p, + space_parser const&) + { + typedef skipper_iteration_policy<> iter_policy_t; + typedef scanner_policies<iter_policy_t> scanner_policies_t; + typedef scanner<IteratorT, scanner_policies_t> scanner_t; + + IteratorT first = first_; + scanner_t scan(first, last); + match<nil_t> hit = p.parse(scan); + return parse_info<IteratorT>( + first, hit, hit && (first == last), + hit.length()); + } + }; + } + + /////////////////////////////////////////////////////////////////////////// + // + // Free parse functions using the skippers + // + /////////////////////////////////////////////////////////////////////////// + template <typename IteratorT, typename ParserT, typename SkipT> + inline parse_info<IteratorT> + parse( + IteratorT const& first, + IteratorT const& last, + parser<ParserT> const& p, + parser<SkipT> const& skip) + { + return impl::phrase_parser<SkipT>:: + parse(first, last, p.derived(), skip.derived()); + } + + /////////////////////////////////////////////////////////////////////////// + // + // Parse function for null terminated strings using the skippers + // + /////////////////////////////////////////////////////////////////////////// + template <typename CharT, typename ParserT, typename SkipT> + inline parse_info<CharT const*> + parse( + CharT const* str, + parser<ParserT> const& p, + parser<SkipT> const& skip) + { + CharT const* last = str; + while (*last) + last++; + return parse(str, last, p, skip); + } + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#endif + diff --git a/boost/spirit/home/classic/core/scanner/scanner.hpp b/boost/spirit/home/classic/core/scanner/scanner.hpp new file mode 100644 index 0000000000..38548770eb --- /dev/null +++ b/boost/spirit/home/classic/core/scanner/scanner.hpp @@ -0,0 +1,329 @@ +/*============================================================================= + Copyright (c) 1998-2002 Joel de Guzman + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_SCANNER_HPP) +#define BOOST_SPIRIT_SCANNER_HPP + +#include <iterator> +#include <boost/config.hpp> +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/match.hpp> +#include <boost/spirit/home/classic/core/non_terminal/parser_id.hpp> +#include <boost/detail/iterator.hpp> // for boost::detail::iterator_traits + +#include <boost/spirit/home/classic/core/scanner/scanner_fwd.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // iteration_policy class + // + /////////////////////////////////////////////////////////////////////////// + struct iteration_policy + { + template <typename ScannerT> + void + advance(ScannerT const& scan) const + { + ++scan.first; + } + + template <typename ScannerT> + bool at_end(ScannerT const& scan) const + { + return scan.first == scan.last; + } + + template <typename T> + T filter(T ch) const + { + return ch; + } + + template <typename ScannerT> + typename ScannerT::ref_t + get(ScannerT const& scan) const + { + return *scan.first; + } + }; + + /////////////////////////////////////////////////////////////////////////// + // + // match_policy class + // + /////////////////////////////////////////////////////////////////////////// + struct match_policy + { + template <typename T> + struct result { typedef match<T> type; }; + + const match<nil_t> + no_match() const + { + return match<nil_t>(); + } + + const match<nil_t> + empty_match() const + { + return match<nil_t>(0, nil_t()); + } + + template <typename AttrT, typename IteratorT> + match<AttrT> + create_match( + std::size_t length, + AttrT const& val, + IteratorT const& /*first*/, + IteratorT const& /*last*/) const + { + return match<AttrT>(length, val); + } + + template <typename MatchT, typename IteratorT> + void group_match( + MatchT& /*m*/, + parser_id const& /*id*/, + IteratorT const& /*first*/, + IteratorT const& /*last*/) const {} + + template <typename Match1T, typename Match2T> + void concat_match(Match1T& l, Match2T const& r) const + { + l.concat(r); + } + }; + + /////////////////////////////////////////////////////////////////////////// + // + // match_result class + // + /////////////////////////////////////////////////////////////////////////// + template <typename MatchPolicyT, typename T> + struct match_result + { + typedef typename MatchPolicyT::template result<T>::type type; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // action_policy class + // + /////////////////////////////////////////////////////////////////////////// + template <typename AttrT> + struct attributed_action_policy + { + template <typename ActorT, typename IteratorT> + static void + call( + ActorT const& actor, + AttrT& val, + IteratorT const&, + IteratorT const&) + { + actor(val); + } + }; + + ////////////////////////////////// + template <> + struct attributed_action_policy<nil_t> + { + template <typename ActorT, typename IteratorT> + static void + call( + ActorT const& actor, + nil_t, + IteratorT const& first, + IteratorT const& last) + { + actor(first, last); + } + }; + + ////////////////////////////////// + struct action_policy + { + template <typename ActorT, typename AttrT, typename IteratorT> + void + do_action( + ActorT const& actor, + AttrT& val, + IteratorT const& first, + IteratorT const& last) const + { + attributed_action_policy<AttrT>::call(actor, val, first, last); + } + }; + + /////////////////////////////////////////////////////////////////////////// + // + // scanner_policies class + // + /////////////////////////////////////////////////////////////////////////// + template < + typename IterationPolicyT, + typename MatchPolicyT, + typename ActionPolicyT> + struct scanner_policies : + public IterationPolicyT, + public MatchPolicyT, + public ActionPolicyT + { + typedef IterationPolicyT iteration_policy_t; + typedef MatchPolicyT match_policy_t; + typedef ActionPolicyT action_policy_t; + + scanner_policies( + IterationPolicyT const& i_policy = IterationPolicyT(), + MatchPolicyT const& m_policy = MatchPolicyT(), + ActionPolicyT const& a_policy = ActionPolicyT()) + : IterationPolicyT(i_policy) + , MatchPolicyT(m_policy) + , ActionPolicyT(a_policy) {} + + template <typename ScannerPoliciesT> + scanner_policies(ScannerPoliciesT const& policies) + : IterationPolicyT(policies) + , MatchPolicyT(policies) + , ActionPolicyT(policies) {} + }; + + /////////////////////////////////////////////////////////////////////////// + // + // scanner_policies_base class: the base class of all scanners + // + /////////////////////////////////////////////////////////////////////////// + struct scanner_base {}; + + /////////////////////////////////////////////////////////////////////////// + // + // scanner class + // + /////////////////////////////////////////////////////////////////////////// + template < + typename IteratorT, + typename PoliciesT> + class scanner : public PoliciesT, public scanner_base + { + public: + + typedef IteratorT iterator_t; + typedef PoliciesT policies_t; + + typedef typename boost::detail:: + iterator_traits<IteratorT>::value_type value_t; + typedef typename boost::detail:: + iterator_traits<IteratorT>::reference ref_t; + typedef typename boost:: + call_traits<IteratorT>::param_type iter_param_t; + + scanner( + IteratorT& first_, + iter_param_t last_, + PoliciesT const& policies = PoliciesT()) + : PoliciesT(policies), first(first_), last(last_) + { + at_end(); + } + + scanner(scanner const& other) + : PoliciesT(other), first(other.first), last(other.last) {} + + scanner(scanner const& other, IteratorT& first_) + : PoliciesT(other), first(first_), last(other.last) {} + + template <typename PoliciesT1> + scanner(scanner<IteratorT, PoliciesT1> const& other) + : PoliciesT(other), first(other.first), last(other.last) {} + + bool + at_end() const + { + typedef typename PoliciesT::iteration_policy_t iteration_policy_type; + return iteration_policy_type::at_end(*this); + } + + value_t + operator*() const + { + typedef typename PoliciesT::iteration_policy_t iteration_policy_type; + return iteration_policy_type::filter(iteration_policy_type::get(*this)); + } + + scanner const& + operator++() const + { + typedef typename PoliciesT::iteration_policy_t iteration_policy_type; + iteration_policy_type::advance(*this); + return *this; + } + + template <typename PoliciesT2> + struct rebind_policies + { + typedef scanner<IteratorT, PoliciesT2> type; + }; + + template <typename PoliciesT2> + scanner<IteratorT, PoliciesT2> + change_policies(PoliciesT2 const& policies) const + { + return scanner<IteratorT, PoliciesT2>(first, last, policies); + } + + template <typename IteratorT2> + struct rebind_iterator + { + typedef scanner<IteratorT2, PoliciesT> type; + }; + + template <typename IteratorT2> + scanner<IteratorT2, PoliciesT> + change_iterator(IteratorT2 const& first_, IteratorT2 const &last_) const + { + return scanner<IteratorT2, PoliciesT>(first_, last_, *this); + } + + IteratorT& first; + IteratorT const last; + + private: + + scanner& + operator=(scanner const& other); + }; + + /////////////////////////////////////////////////////////////////////////// + // + // rebind_scanner_policies class + // + /////////////////////////////////////////////////////////////////////////// + template <typename ScannerT, typename PoliciesT> + struct rebind_scanner_policies + { + typedef typename ScannerT::template + rebind_policies<PoliciesT>::type type; + }; + + ////////////////////////////////// + template <typename ScannerT, typename IteratorT> + struct rebind_scanner_iterator + { + typedef typename ScannerT::template + rebind_iterator<IteratorT>::type type; + }; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} + +#endif diff --git a/boost/spirit/home/classic/core/scanner/scanner_fwd.hpp b/boost/spirit/home/classic/core/scanner/scanner_fwd.hpp new file mode 100644 index 0000000000..efd78cfa54 --- /dev/null +++ b/boost/spirit/home/classic/core/scanner/scanner_fwd.hpp @@ -0,0 +1,52 @@ +/*============================================================================= + Copyright (c) 2006 Tobias Schwinger + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_SCANNER_FWD_HPP) +#define BOOST_SPIRIT_SCANNER_FWD_HPP + +#include <boost/spirit/home/classic/namespace.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // policy classes + // + /////////////////////////////////////////////////////////////////////////// + struct iteration_policy; + struct action_policy; + struct match_policy; + + /////////////////////////////////////////////////////////////////////////// + // + // scanner_policies class + // + /////////////////////////////////////////////////////////////////////////// + template < + typename IterationPolicyT = iteration_policy, + typename MatchPolicyT = match_policy, + typename ActionPolicyT = action_policy> + struct scanner_policies; + + /////////////////////////////////////////////////////////////////////////// + // + // scanner class + // + /////////////////////////////////////////////////////////////////////////// + template < + typename IteratorT = char const*, + typename PoliciesT = scanner_policies<> > + class scanner; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + diff --git a/boost/spirit/home/classic/core/scanner/skipper.hpp b/boost/spirit/home/classic/core/scanner/skipper.hpp new file mode 100644 index 0000000000..4e655aeafe --- /dev/null +++ b/boost/spirit/home/classic/core/scanner/skipper.hpp @@ -0,0 +1,197 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_SKIPPER_HPP) +#define BOOST_SPIRIT_SKIPPER_HPP + +/////////////////////////////////////////////////////////////////////////////// +#include <cctype> + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/scanner/scanner.hpp> +#include <boost/spirit/home/classic/core/primitives/impl/primitives.ipp> + +#include <boost/spirit/home/classic/core/scanner/skipper_fwd.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // skipper_iteration_policy class + // + /////////////////////////////////////////////////////////////////////////// + template <typename BaseT> + struct skipper_iteration_policy : public BaseT + { + typedef BaseT base_t; + + skipper_iteration_policy() + : BaseT() {} + + template <typename PolicyT> + skipper_iteration_policy(PolicyT const& other) + : BaseT(other) {} + + template <typename ScannerT> + void + advance(ScannerT const& scan) const + { + BaseT::advance(scan); + scan.skip(scan); + } + + template <typename ScannerT> + bool + at_end(ScannerT const& scan) const + { + scan.skip(scan); + return BaseT::at_end(scan); + } + + template <typename ScannerT> + void + skip(ScannerT const& scan) const + { + while (!BaseT::at_end(scan) && impl::isspace_(BaseT::get(scan))) + BaseT::advance(scan); + } + }; + + /////////////////////////////////////////////////////////////////////////// + // + // no_skipper_iteration_policy class + // + /////////////////////////////////////////////////////////////////////////// + template <typename BaseT> + struct no_skipper_iteration_policy : public BaseT + { + typedef BaseT base_t; + + no_skipper_iteration_policy() + : BaseT() {} + + template <typename PolicyT> + no_skipper_iteration_policy(PolicyT const& other) + : BaseT(other) {} + + template <typename ScannerT> + void + skip(ScannerT const& /*scan*/) const {} + }; + + /////////////////////////////////////////////////////////////////////////// + // + // skip_parser_iteration_policy class + // + /////////////////////////////////////////////////////////////////////////// + namespace impl + { + template <typename ST, typename ScannerT, typename BaseT> + void + skipper_skip( + ST const& s, + ScannerT const& scan, + skipper_iteration_policy<BaseT> const&); + + template <typename ST, typename ScannerT, typename BaseT> + void + skipper_skip( + ST const& s, + ScannerT const& scan, + no_skipper_iteration_policy<BaseT> const&); + + template <typename ST, typename ScannerT> + void + skipper_skip( + ST const& s, + ScannerT const& scan, + iteration_policy const&); + } + + template <typename ParserT, typename BaseT> + class skip_parser_iteration_policy : public skipper_iteration_policy<BaseT> + { + public: + + typedef skipper_iteration_policy<BaseT> base_t; + + skip_parser_iteration_policy( + ParserT const& skip_parser, + base_t const& base = base_t()) + : base_t(base), subject(skip_parser) {} + + template <typename PolicyT> + skip_parser_iteration_policy(PolicyT const& other) + : base_t(other), subject(other.skipper()) {} + + template <typename ScannerT> + void + skip(ScannerT const& scan) const + { + impl::skipper_skip(subject, scan, scan); + } + + ParserT const& + skipper() const + { + return subject; + } + + private: + + ParserT const& subject; + }; + + /////////////////////////////////////////////////////////////////////////////// + // + // Free parse functions using the skippers + // + /////////////////////////////////////////////////////////////////////////////// + template <typename IteratorT, typename ParserT, typename SkipT> + parse_info<IteratorT> + parse( + IteratorT const& first, + IteratorT const& last, + parser<ParserT> const& p, + parser<SkipT> const& skip); + + /////////////////////////////////////////////////////////////////////////////// + // + // Parse function for null terminated strings using the skippers + // + /////////////////////////////////////////////////////////////////////////////// + template <typename CharT, typename ParserT, typename SkipT> + parse_info<CharT const*> + parse( + CharT const* str, + parser<ParserT> const& p, + parser<SkipT> const& skip); + + /////////////////////////////////////////////////////////////////////////////// + // + // phrase_scanner_t and wide_phrase_scanner_t + // + // The most common scanners. Use these typedefs when you need + // a scanner that skips white spaces. + // + /////////////////////////////////////////////////////////////////////////////// + typedef skipper_iteration_policy<> iter_policy_t; + typedef scanner_policies<iter_policy_t> scanner_policies_t; + typedef scanner<char const*, scanner_policies_t> phrase_scanner_t; + typedef scanner<wchar_t const*, scanner_policies_t> wide_phrase_scanner_t; + + /////////////////////////////////////////////////////////////////////////////// + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#include <boost/spirit/home/classic/core/scanner/impl/skipper.ipp> +#endif + diff --git a/boost/spirit/home/classic/core/scanner/skipper_fwd.hpp b/boost/spirit/home/classic/core/scanner/skipper_fwd.hpp new file mode 100644 index 0000000000..228e618bac --- /dev/null +++ b/boost/spirit/home/classic/core/scanner/skipper_fwd.hpp @@ -0,0 +1,32 @@ +/*============================================================================= + Copyright (c) 2006 Tobias Schwinger + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_SKIPPER_FWD_HPP) +#define BOOST_SPIRIT_SKIPPER_FWD_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/scanner/scanner_fwd.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + template <typename BaseT = iteration_policy> + struct skipper_iteration_policy; + + template <typename BaseT = iteration_policy> + struct no_skipper_iteration_policy; + + template <typename ParserT, typename BaseT = iteration_policy> + class skip_parser_iteration_policy; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + diff --git a/boost/spirit/home/classic/core/typeof.hpp b/boost/spirit/home/classic/core/typeof.hpp new file mode 100644 index 0000000000..ca82428415 --- /dev/null +++ b/boost/spirit/home/classic/core/typeof.hpp @@ -0,0 +1,343 @@ +/*============================================================================= + Copyright (c) 2006 Tobias Schwinger + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_CORE_TYPEOF_HPP) +#define BOOST_SPIRIT_CORE_TYPEOF_HPP + +#include <boost/config.hpp> +#include <boost/cstdint.hpp> + +#include <boost/typeof/typeof.hpp> + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/nil.hpp> +#include <boost/spirit/home/classic/core/primitives/numerics_fwd.hpp> +#include <boost/spirit/home/classic/core/scanner/scanner_fwd.hpp> +#include <boost/spirit/home/classic/core/scanner/skipper_fwd.hpp> +#include <boost/spirit/home/classic/core/non_terminal/subrule_fwd.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + // parser.hpp + template <typename IteratorT> struct parse_info; + struct plain_parser_category; + struct binary_parser_category; + struct unary_parser_category; + struct action_parser_category; + + // match.hpp + template<typename T> class match; + + // primitives/primitives.hpp + template<class ParserT> struct negated_char_parser; + template<typename CharT> struct chlit; + template<typename CharT> struct range; + template<typename IteratorT> class chseq; + template<typename IteratorT> class strlit; + struct nothing_parser; + struct anychar_parser; + struct alnum_parser; + struct alpha_parser; + struct cntrl_parser; + struct digit_parser; + struct xdigit_parser; + struct graph_parser; + struct upper_parser; + struct lower_parser; + struct print_parser; + struct punct_parser; + struct blank_parser; + struct space_parser; + struct eol_parser; + struct end_parser; + + // non_terminal/parser_context.hpp + template<typename T> struct parser_context; + + // non_terminal/parser_id.hpp + class parser_id; + template<int N> struct parser_tag; + class dynamic_parser_tag; + struct parser_address_tag; + + // non_terminal/rule.hpp + template<typename T0, typename T1, typename T2> class rule; + + // non_terminal/grammar.hpp + template<class DerivedT, typename ContextT> struct grammar; + + // composite.hpp + template<class ParserT, typename ActionT> class action; + template<class A, class B> struct alternative; + template<class A, class B> struct difference; + template<class A, class B> struct exclusive_or; + template<class A, class B> struct intersection; + template<class a, class b> struct sequence; + template<class A, class B> struct sequential_or; + template<class S> struct kleene_star; + template<class S> struct positive; + template<class S> struct optional; + // composite/directives.hpp + template<class ParserT> struct contiguous; + template<class ParserT> struct inhibit_case; + template<class BaseT> struct inhibit_case_iteration_policy; + template<class A, class B> struct longest_alternative; + template<class A, class B> struct shortest_alternative; + template<class ParserT, typename BoundsT> struct min_bounded; + template<class ParserT, typename BoundsT> struct max_bounded; + template<class ParserT, typename BoundsT> struct bounded; + // composite/no_actions.hpp + template<class Parser> struct no_actions_parser; + template<class Base> struct no_actions_action_policy; + // composite/epsilon.hpp + struct epsilon_parser; + template<typename CondT, bool positive> struct condition_parser; + template<typename SubjectT> struct empty_match_parser; + template<typename SubjectT> struct negated_empty_match_parser; + + // deprecated assign/push_back actor -- they live somewhere else, now + struct assign_action; + struct push_back_action; + template<typename T, typename ActionT> class ref_value_actor; + template<typename T, typename ValueT, typename ActionT> + class ref_const_ref_actor; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + + + +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() + + +// parser.hpp + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::parse_info,1) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::plain_parser_category) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::binary_parser_category) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::unary_parser_category) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::action_parser_category) + + +// nil.hpp (included directly) + +#if !defined(BOOST_SPIRIT_NIL_T_TYPEOF_REGISTERED) +// registration guard to decouple the iterators from the core +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::nil_t) +# define BOOST_SPIRIT_NIL_T_TYPEOF_REGISTERED +#endif + +// match.hpp + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::match, 1) + +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::match<BOOST_SPIRIT_CLASSIC_NS::nil_t>) + + +// primitives/primitives.hpp + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::negated_char_parser, 1) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::chlit, 1) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::range, 1) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::chseq, 1) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::strlit, 1) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::nothing_parser) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::anychar_parser) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::alnum_parser) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::alpha_parser) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::cntrl_parser) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::digit_parser) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::xdigit_parser) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::graph_parser) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::upper_parser) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::lower_parser) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::print_parser) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::punct_parser) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::blank_parser) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::space_parser) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::eol_parser) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::end_parser) + +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::chlit<char>) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::chlit<wchar_t>) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::range<char>) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::range<wchar_t>) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::chseq<char const *>) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::chseq<wchar_t const *>) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::strlit<char const *>) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::strlit<wchar_t const *>) + + +// primitives/numerics.hpp (has forward header) + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::int_parser, (class)(int)(unsigned)(int)) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::uint_parser, (class)(int)(unsigned)(int)) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::sign_parser) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::real_parser, 2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::real_parser_policies, 1) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::ureal_parser_policies, 1) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::strict_real_parser_policies, 1) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::strict_ureal_parser_policies, 1) + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::int_parser, (class)(int)) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::uint_parser, (class)(int)) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::int_parser<boost::int32_t>) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::uint_parser<boost::uint32_t>) +#if !defined(BOOST_NO_INT64_T) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::int_parser<boost::int64_t>) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::uint_parser<boost::uint64_t>) +#endif +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::real_parser_policies<float>) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::real_parser_policies<double>) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::ureal_parser_policies<float>) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::ureal_parser_policies<double>) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::strict_real_parser_policies<float>) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::strict_real_parser_policies<double>) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::strict_ureal_parser_policies<float>) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::strict_ureal_parser_policies<double>) + + +// scanner/scanner.hpp (has forward header) + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::scanner,2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::scanner_policies,3) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::iteration_policy) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::action_policy) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::match_policy) + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::scanner,1) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::scanner_policies,2) + + +// scanner/skipper.hpp (has forward header) + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::skipper_iteration_policy,1) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::no_skipper_iteration_policy,1) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::skip_parser_iteration_policy,2) + +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::skipper_iteration_policy<>) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::skip_parser_iteration_policy,1) + + +// non_terminal/parser_context.hpp + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::parser_context,1) + +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::parser_context<BOOST_SPIRIT_CLASSIC_NS::nil_t>) + + +// non_terminal/parser_id.hpp + +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::parser_id) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::parser_tag, (int)) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::dynamic_parser_tag) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::parser_address_tag) + + +// non_terminal/subrule.hpp (has forward header) + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::subrule,(int)(class)) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::subrule_parser,(int)(class)(class)) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::subrule_list,2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::subrules_scanner,2) + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::subrule,(int)) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::subrule_parser,(int)(class)) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::subrule<0>) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::subrule<1>) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::subrule<2>) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::subrule<3>) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::subrule<4>) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::subrule<5>) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::subrule<6>) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::subrule<7>) + + +// non_terminal/rule.hpp + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::rule,3) +#if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1 +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::scanner_list,1) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::scanner_list,BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT) +#endif + + +// non_terminal/grammar.hpp + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::grammar,2) + + +// composite.hpp + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::action, 2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::alternative, 2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::difference, 2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::exclusive_or, 2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::intersection, 2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::sequence, 2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::sequential_or, 2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::kleene_star, 1) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::positive, 1) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::optional, 1) + + +// composite/directives.hpp + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::contiguous, 1) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::inhibit_case, 1) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::inhibit_case_iteration_policy,1) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::longest_alternative, 2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::shortest_alternative, 2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::min_bounded, 2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::max_bounded, 2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::bounded, 2) + + +// composite/no_actions.hpp + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::no_actions_parser, 1) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::no_actions_action_policy, 1) + +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::no_actions_action_policy<BOOST_SPIRIT_CLASSIC_NS::action_policy>) + + +// composite/epsilon.hpp + +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::epsilon_parser) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::condition_parser, (class)(bool)) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::empty_match_parser, 1) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::negated_empty_match_parser, 1) + + +#if !defined(BOOST_SPIRIT_ACTOR_TYPEOF_HPP) +// deprecated assign/push_back actor -- they live somewhere else, now +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::ref_value_actor,2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::ref_const_ref_actor,3) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::assign_action) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::push_back_action) +#endif + + +#if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1400)) && BOOST_MSVC >= 1400 +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + nil_t & operator* (nil_t); + nil_t & operator+ (nil_t); + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +} } // namespace ::BOOST_SPIRIT_CLASSIC_NS +#endif + + +#endif + diff --git a/boost/spirit/home/classic/debug.hpp b/boost/spirit/home/classic/debug.hpp new file mode 100644 index 0000000000..9737b35bee --- /dev/null +++ b/boost/spirit/home/classic/debug.hpp @@ -0,0 +1,154 @@ +/*============================================================================= + Copyright (c) 2001-2003 Joel de Guzman + Copyright (c) 2002-2003 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_DEBUG_MAIN_HPP) +#define BOOST_SPIRIT_DEBUG_MAIN_HPP + +/////////////////////////////////////////////////////////////////////////// +#if defined(BOOST_SPIRIT_DEBUG) + +#include <boost/spirit/home/classic/version.hpp> + +/////////////////////////////////////////////////////////////////////////////// +// +// Spirit.Debug includes and defines +// +/////////////////////////////////////////////////////////////////////////////// + + #include <iostream> + + /////////////////////////////////////////////////////////////////////////// + // + // The BOOST_SPIRIT_DEBUG_OUT defines the stream object, which should be used + // for debug diagnostics. This defaults to std::cout. + // + /////////////////////////////////////////////////////////////////////////// + #if !defined(BOOST_SPIRIT_DEBUG_OUT) + #define BOOST_SPIRIT_DEBUG_OUT std::cout + #endif + + /////////////////////////////////////////////////////////////////////////// + // + // The BOOST_SPIRIT_DEBUG_PRINT_SOME constant defines the number of characters + // from the stream to be printed for diagnosis. This defaults to the first + // 20 characters. + // + /////////////////////////////////////////////////////////////////////////// + #if !defined(BOOST_SPIRIT_DEBUG_PRINT_SOME) + #define BOOST_SPIRIT_DEBUG_PRINT_SOME 20 + #endif + + /////////////////////////////////////////////////////////////////////////// + // + // Additional BOOST_SPIRIT_DEBUG_FLAGS control the level of diagnostics printed + // Basic constants are defined in debug/minimal.hpp. + // + /////////////////////////////////////////////////////////////////////////// + #define BOOST_SPIRIT_DEBUG_FLAGS_NODES 0x0001 // node diagnostics + #define BOOST_SPIRIT_DEBUG_FLAGS_ESCAPE_CHAR 0x0002 // escape_char_parse diagnostics + #define BOOST_SPIRIT_DEBUG_FLAGS_TREES 0x0004 // parse tree/ast diagnostics + #define BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES 0x0008 // closure diagnostics + #define BOOST_SPIRIT_DEBUG_FLAGS_SLEX 0x8000 // slex diagnostics + + #define BOOST_SPIRIT_DEBUG_FLAGS_MAX 0xFFFF // print maximal diagnostics + + #if !defined(BOOST_SPIRIT_DEBUG_FLAGS) + #define BOOST_SPIRIT_DEBUG_FLAGS BOOST_SPIRIT_DEBUG_FLAGS_MAX + #endif + + /////////////////////////////////////////////////////////////////////////// + // + // By default all nodes are traced (even those, not registered with + // BOOST_SPIRIT_DEBUG_RULE et.al. - see below). The following constant may be + // used to redefine this default. + // + /////////////////////////////////////////////////////////////////////////// + #if !defined(BOOST_SPIRIT_DEBUG_TRACENODE) + #define BOOST_SPIRIT_DEBUG_TRACENODE (true) + #endif // !defined(BOOST_SPIRIT_DEBUG_TRACENODE) + + /////////////////////////////////////////////////////////////////////////// + // + // Helper macros for giving rules and subrules a name accessible through + // parser_name() functions (see parser_names.hpp). + // + // Additionally, the macros BOOST_SPIRIT_DEBUG_RULE, SPIRIT_DEBUG_NODE and + // BOOST_SPIRIT_DEBUG_GRAMMAR enable/disable the tracing of the + // correspondingnode accordingly to the PP constant + // BOOST_SPIRIT_DEBUG_TRACENODE. + // + // The macros BOOST_SPIRIT_DEBUG_TRACE_RULE, BOOST_SPIRIT_DEBUG_TRACE_NODE + // and BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR allow to specify a flag to define, + // whether the corresponding node is to be traced or not. + // + /////////////////////////////////////////////////////////////////////////// + #if !defined(BOOST_SPIRIT_DEBUG_RULE) + #define BOOST_SPIRIT_DEBUG_RULE(r) \ + ::BOOST_SPIRIT_CLASSIC_NS::impl::get_node_registry(). \ + register_node(&r, #r, BOOST_SPIRIT_DEBUG_TRACENODE) + #endif // !defined(BOOST_SPIRIT_DEBUG_RULE) + + #if !defined(BOOST_SPIRIT_DEBUG_NODE) + #define BOOST_SPIRIT_DEBUG_NODE(r) \ + ::BOOST_SPIRIT_CLASSIC_NS::impl::get_node_registry(). \ + register_node(&r, #r, BOOST_SPIRIT_DEBUG_TRACENODE) + #endif // !defined(BOOST_SPIRIT_DEBUG_NODE) + + #if !defined(BOOST_SPIRIT_DEBUG_GRAMMAR) + #define BOOST_SPIRIT_DEBUG_GRAMMAR(r) \ + ::BOOST_SPIRIT_CLASSIC_NS::impl::get_node_registry(). \ + register_node(&r, #r, BOOST_SPIRIT_DEBUG_TRACENODE) + #endif // !defined(BOOST_SPIRIT_DEBUG_GRAMMAR) + + #if !defined(BOOST_SPIRIT_DEBUG_TRACE_RULE) + #define BOOST_SPIRIT_DEBUG_TRACE_RULE(r, t) \ + ::BOOST_SPIRIT_CLASSIC_NS::impl::get_node_registry(). \ + register_node(&r, #r, (t)) + #endif // !defined(BOOST_SPIRIT_TRACE_RULE) + + #if !defined(BOOST_SPIRIT_DEBUG_TRACE_NODE) + #define BOOST_SPIRIT_DEBUG_TRACE_NODE(r, t) \ + ::BOOST_SPIRIT_CLASSIC_NS::impl::get_node_registry(). \ + register_node(&r, #r, (t)) + #endif // !defined(BOOST_SPIRIT_DEBUG_TRACE_NODE) + + #if !defined(BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR) + #define BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR(r, t) \ + ::BOOST_SPIRIT_CLASSIC_NS::impl::get_node_registry(). \ + register_node(&r, #r, (t)) + #endif // !defined(BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR) + + #if !defined(BOOST_SPIRIT_DEBUG_TRACE_RULE_NAME) + #define BOOST_SPIRIT_DEBUG_TRACE_RULE_NAME(r, n, t) \ + ::BOOST_SPIRIT_CLASSIC_NS::impl::get_node_registry(). \ + register_node(&r, (n), (t)) + #endif // !defined(BOOST_SPIRIT_DEBUG_TRACE_RULE_NAME) + + #if !defined(BOOST_SPIRIT_DEBUG_TRACE_NODE_NAME) + #define BOOST_SPIRIT_DEBUG_TRACE_NODE_NAME(r, n, t) \ + ::BOOST_SPIRIT_CLASSIC_NS::impl::get_node_registry(). \ + register_node(&r, (n), (t)) + #endif // !defined(BOOST_SPIRIT_DEBUG_TRACE_NODE_NAME) + + #if !defined(BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME) + #define BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(r, n, t) \ + ::BOOST_SPIRIT_CLASSIC_NS::impl::get_node_registry(). \ + register_node(&r, (n), (t)) + #endif // !defined(BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME) + + ////////////////////////////////// + #include <boost/spirit/home/classic/debug/debug_node.hpp> + +#else + ////////////////////////////////// + #include <boost/spirit/home/classic/debug/minimal.hpp> + +#endif // BOOST_SPIRIT_DEBUG + +#endif + diff --git a/boost/spirit/home/classic/debug/debug_node.hpp b/boost/spirit/home/classic/debug/debug_node.hpp new file mode 100644 index 0000000000..adc1f91f22 --- /dev/null +++ b/boost/spirit/home/classic/debug/debug_node.hpp @@ -0,0 +1,319 @@ +/*============================================================================= + Copyright (c) 2001-2003 Joel de Guzman + Copyright (c) 2002-2003 Hartmut Kaiser + Copyright (c) 2003 Gustavo Guerra + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_DEBUG_NODE_HPP) +#define BOOST_SPIRIT_DEBUG_NODE_HPP + +#if !defined(BOOST_SPIRIT_DEBUG_MAIN_HPP) +#error "You must include boost/spirit/debug.hpp, not boost/spirit/debug/debug_node.hpp" +#endif + +#if defined(BOOST_SPIRIT_DEBUG) + +#include <string> + +#include <boost/type_traits/is_convertible.hpp> +#include <boost/mpl/if.hpp> +#include <boost/mpl/and.hpp> +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/primitives/primitives.hpp> // for iscntrl_ + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// +// Debug helper classes for rules, which ensure maximum non-intrusiveness of +// the Spirit debug support +// +/////////////////////////////////////////////////////////////////////////////// + +namespace impl { + + struct token_printer_aux_for_chars + { + template<typename CharT> + static void print(std::ostream& o, CharT c) + { + if (c == static_cast<CharT>('\a')) + o << "\\a"; + + else if (c == static_cast<CharT>('\b')) + o << "\\b"; + + else if (c == static_cast<CharT>('\f')) + o << "\\f"; + + else if (c == static_cast<CharT>('\n')) + o << "\\n"; + + else if (c == static_cast<CharT>('\r')) + o << "\\r"; + + else if (c == static_cast<CharT>('\t')) + o << "\\t"; + + else if (c == static_cast<CharT>('\v')) + o << "\\v"; + + else if (iscntrl_(c)) + o << "\\" << static_cast<int>(c); + + else + o << static_cast<char>(c); + } + }; + + // for token types where the comparison with char constants wouldn't work + struct token_printer_aux_for_other_types + { + template<typename CharT> + static void print(std::ostream& o, CharT c) + { + o << c; + } + }; + + template <typename CharT> + struct token_printer_aux + : mpl::if_< + mpl::and_< + is_convertible<CharT, char>, + is_convertible<char, CharT> >, + token_printer_aux_for_chars, + token_printer_aux_for_other_types + >::type + { + }; + + template<typename CharT> + inline void token_printer(std::ostream& o, CharT c) + { + #if !defined(BOOST_SPIRIT_DEBUG_TOKEN_PRINTER) + + token_printer_aux<CharT>::print(o, c); + + #else + + BOOST_SPIRIT_DEBUG_TOKEN_PRINTER(o, c); + + #endif + } + +/////////////////////////////////////////////////////////////////////////////// +// +// Dump infos about the parsing state of a rule +// +/////////////////////////////////////////////////////////////////////////////// + +#if BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES + template <typename IteratorT> + inline void + print_node_info(bool hit, int level, bool close, std::string const& name, + IteratorT first, IteratorT last) + { + if (!name.empty()) + { + for (int i = 0; i < level; ++i) + BOOST_SPIRIT_DEBUG_OUT << " "; + if (close) + { + if (hit) + BOOST_SPIRIT_DEBUG_OUT << "/"; + else + BOOST_SPIRIT_DEBUG_OUT << "#"; + } + BOOST_SPIRIT_DEBUG_OUT << name << ":\t\""; + IteratorT iter = first; + IteratorT ilast = last; + for (int j = 0; j < BOOST_SPIRIT_DEBUG_PRINT_SOME; ++j) + { + if (iter == ilast) + break; + + token_printer(BOOST_SPIRIT_DEBUG_OUT, *iter); + ++iter; + } + BOOST_SPIRIT_DEBUG_OUT << "\"\n"; + } + } +#endif // BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES + +#if BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES + template <typename ResultT> + inline ResultT & + print_closure_info(ResultT &hit, int level, std::string const& name) + { + if (!name.empty()) + { + for (int i = 0; i < level-1; ++i) + BOOST_SPIRIT_DEBUG_OUT << " "; + + // for now, print out the return value only + BOOST_SPIRIT_DEBUG_OUT << "^" << name << ":\t"; + if (hit.has_valid_attribute()) + BOOST_SPIRIT_DEBUG_OUT << hit.value(); + else + BOOST_SPIRIT_DEBUG_OUT << "undefined attribute"; + BOOST_SPIRIT_DEBUG_OUT << "\n"; + } + return hit; + } +#endif // BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES + +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Implementation note: The parser_context_linker, parser_scanner_linker and +// closure_context_linker classes are wrapped by a PP constant to allow +// redefinition of this classes outside of Spirit +// +/////////////////////////////////////////////////////////////////////////////// +#if !defined(BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED) +#define BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED + + /////////////////////////////////////////////////////////////////////////// + // + // parser_context_linker is a debug wrapper for the ContextT template + // parameter of the rule<>, subrule<> and the grammar<> classes + // + /////////////////////////////////////////////////////////////////////////// + template<typename ContextT> + struct parser_context_linker : public ContextT + { + typedef ContextT base_t; + + template <typename ParserT> + parser_context_linker(ParserT const& p) + : ContextT(p) {} + + template <typename ParserT, typename ScannerT> + void pre_parse(ParserT const& p, ScannerT &scan) + { + this->base_t::pre_parse(p, scan); + +#if BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES + if (trace_parser(p.derived())) { + impl::print_node_info( + false, + scan.get_level(), + false, + parser_name(p.derived()), + scan.first, + scan.last); + } + scan.get_level()++; +#endif // BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES + } + + template <typename ResultT, typename ParserT, typename ScannerT> + ResultT& post_parse(ResultT& hit, ParserT const& p, ScannerT &scan) + { +#if BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES + --scan.get_level(); + if (trace_parser(p.derived())) { + impl::print_node_info( + hit, + scan.get_level(), + true, + parser_name(p.derived()), + scan.first, + scan.last); + } +#endif // BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES + + return this->base_t::post_parse(hit, p, scan); + } + }; + +#endif // !defined(BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED) + +#if !defined(BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED) +#define BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED + +/////////////////////////////////////////////////////////////////////////////// +// This class is to avoid linker problems and to ensure a real singleton +// 'level' variable + struct debug_support + { + int& get_level() + { + static int level = 0; + return level; + } + }; + + template<typename ScannerT> + struct parser_scanner_linker : public ScannerT + { + parser_scanner_linker(ScannerT const &scan_) : ScannerT(scan_) + {} + + int &get_level() + { return debug.get_level(); } + + private: debug_support debug; + }; + +#endif // !defined(BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED) + +#if !defined(BOOST_SPIRIT_CLOSURE_CONTEXT_LINKER_DEFINED) +#define BOOST_SPIRIT_CLOSURE_CONTEXT_LINKER_DEFINED + + /////////////////////////////////////////////////////////////////////////// + // + // closure_context_linker is a debug wrapper for the closure template + // parameter of the rule<>, subrule<> and grammar classes + // + /////////////////////////////////////////////////////////////////////////// + + template<typename ContextT> + struct closure_context_linker : public parser_context_linker<ContextT> + { + typedef parser_context_linker<ContextT> base_t; + + template <typename ParserT> + closure_context_linker(ParserT const& p) + : parser_context_linker<ContextT>(p) {} + + template <typename ParserT, typename ScannerT> + void pre_parse(ParserT const& p, ScannerT &scan) + { this->base_t::pre_parse(p, scan); } + + template <typename ResultT, typename ParserT, typename ScannerT> + ResultT& + post_parse(ResultT& hit, ParserT const& p, ScannerT &scan) + { +#if BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES + if (hit && trace_parser(p.derived())) { + // for now, print out the return value only + return impl::print_closure_info( + this->base_t::post_parse(hit, p, scan), + scan.get_level(), + parser_name(p.derived()) + ); + } +#endif // BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES + + return this->base_t::post_parse(hit, p, scan); + } + }; + +#endif // !defined(BOOST_SPIRIT_CLOSURE_CONTEXT_LINKER_DEFINED) + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif // defined(BOOST_SPIRIT_DEBUG) + +#endif // !defined(BOOST_SPIRIT_DEBUG_NODE_HPP) + diff --git a/boost/spirit/home/classic/debug/impl/parser_names.ipp b/boost/spirit/home/classic/debug/impl/parser_names.ipp new file mode 100644 index 0000000000..5d75be2436 --- /dev/null +++ b/boost/spirit/home/classic/debug/impl/parser_names.ipp @@ -0,0 +1,555 @@ +/*============================================================================= + Copyright (c) 2001-2003 Joel de Guzman + Copyright (c) 2002-2003 Hartmut Kaiser + 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) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_PARSER_NAMES_IPP) +#define BOOST_SPIRIT_PARSER_NAMES_IPP + +#if defined(BOOST_SPIRIT_DEBUG) + +#include <string> +#include <iostream> +#include <map> + +#include <boost/config.hpp> +#ifdef BOOST_NO_STRINGSTREAM +#include <strstream> +#define BOOST_SPIRIT_SSTREAM std::strstream +std::string BOOST_SPIRIT_GETSTRING(std::strstream& ss) +{ + ss << ends; + std::string rval = ss.str(); + ss.freeze(false); + return rval; +} +#else +#include <sstream> +#define BOOST_SPIRIT_GETSTRING(ss) ss.str() +#define BOOST_SPIRIT_SSTREAM std::stringstream +#endif + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// from actions.hpp + template <typename ParserT, typename ActionT> + inline std::string + parser_name(action<ParserT, ActionT> const& p) + { + return std::string("action") + + std::string("[") + + parser_name(p.subject()) + + std::string("]"); + } + +/////////////////////////////////////////////////////////////////////////////// +// from directives.hpp + template <typename ParserT> + inline std::string + parser_name(contiguous<ParserT> const& p) + { + return std::string("contiguous") + + std::string("[") + + parser_name(p.subject()) + + std::string("]"); + } + + template <typename ParserT> + inline std::string + parser_name(inhibit_case<ParserT> const& p) + { + return std::string("inhibit_case") + + std::string("[") + + parser_name(p.subject()) + + std::string("]"); + } + + template <typename A, typename B> + inline std::string + parser_name(longest_alternative<A, B> const& p) + { + return std::string("longest_alternative") + + std::string("[") + + parser_name(p.left()) + std::string(", ") + parser_name(p.right()) + + std::string("]"); + } + + template <typename A, typename B> + inline std::string + parser_name(shortest_alternative<A, B> const& p) + { + return std::string("shortest_alternative") + + std::string("[") + + parser_name(p.left()) + std::string(", ") + parser_name(p.right()) + + std::string("]"); + } + +/////////////////////////////////////////////////////////////////////////////// +// from numerics.hpp + template <typename T, int Radix, unsigned MinDigits, int MaxDigits> + inline std::string + parser_name(uint_parser<T, Radix, MinDigits, MaxDigits> const& p) + { + BOOST_SPIRIT_SSTREAM stream; + stream << Radix << ", " << MinDigits << ", " << MaxDigits; + return std::string("uint_parser<") + + BOOST_SPIRIT_GETSTRING(stream) + + std::string(">"); + } + + template <typename T, int Radix, unsigned MinDigits, int MaxDigits> + inline std::string + parser_name(int_parser<T, Radix, MinDigits, MaxDigits> const& p) + { + BOOST_SPIRIT_SSTREAM stream; + stream << Radix << ", " << MinDigits << ", " << MaxDigits; + return std::string("int_parser<") + + BOOST_SPIRIT_GETSTRING(stream) + + std::string(">"); + } + + template <typename T, typename RealPoliciesT> + inline std::string + parser_name(real_parser<T, RealPoliciesT> const& p) + { + return std::string("real_parser"); + } + +/////////////////////////////////////////////////////////////////////////////// +// from operators.hpp + template <typename A, typename B> + inline std::string + parser_name(sequence<A, B> const& p) + { + return std::string("sequence") + + std::string("[") + + parser_name(p.left()) + std::string(", ") + parser_name(p.right()) + + std::string("]"); + } + + template <typename A, typename B> + inline std::string + parser_name(sequential_or<A, B> const& p) + { + return std::string("sequential_or") + + std::string("[") + + parser_name(p.left()) + std::string(", ") + parser_name(p.right()) + + std::string("]"); + } + + template <typename A, typename B> + inline std::string + parser_name(alternative<A, B> const& p) + { + return std::string("alternative") + + std::string("[") + + parser_name(p.left()) + std::string(", ") + parser_name(p.right()) + + std::string("]"); + } + + template <typename A, typename B> + inline std::string + parser_name(intersection<A, B> const& p) + { + return std::string("intersection") + + std::string("[") + + parser_name(p.left()) + std::string(", ") + parser_name(p.right()) + + std::string("]"); + } + + template <typename A, typename B> + inline std::string + parser_name(difference<A, B> const& p) + { + return std::string("difference") + + std::string("[") + + parser_name(p.left()) + std::string(", ") + parser_name(p.right()) + + std::string("]"); + } + + template <typename A, typename B> + inline std::string + parser_name(exclusive_or<A, B> const& p) + { + return std::string("exclusive_or") + + std::string("[") + + parser_name(p.left()) + std::string(", ") + parser_name(p.right()) + + std::string("]"); + } + + template <typename S> + inline std::string + parser_name(optional<S> const& p) + { + return std::string("optional") + + std::string("[") + + parser_name(p.subject()) + + std::string("]"); + } + + template <typename S> + inline std::string + parser_name(kleene_star<S> const& p) + { + return std::string("kleene_star") + + std::string("[") + + parser_name(p.subject()) + + std::string("]"); + } + + template <typename S> + inline std::string + parser_name(positive<S> const& p) + { + return std::string("positive") + + std::string("[") + + parser_name(p.subject()) + + std::string("]"); + } + +/////////////////////////////////////////////////////////////////////////////// +// from parser.hpp + template <typename DerivedT> + inline std::string + parser_name(parser<DerivedT> const& p) + { + return std::string("parser"); + } + +/////////////////////////////////////////////////////////////////////////////// +// from primitives.hpp + template <typename DerivedT> + inline std::string + parser_name(char_parser<DerivedT> const &p) + { + return std::string("char_parser"); + } + + template <typename CharT> + inline std::string + parser_name(chlit<CharT> const &p) + { + return std::string("chlit(\'") + + std::string(1, p.ch) + + std::string("\')"); + } + + template <typename CharT> + inline std::string + parser_name(range<CharT> const &p) + { + return std::string("range(") + + std::string(1, p.first) + std::string(", ") + std::string(1, p.last) + + std::string(")"); + } + + template <typename IteratorT> + inline std::string + parser_name(chseq<IteratorT> const &p) + { + return std::string("chseq(\"") + + std::string(p.first, p.last) + + std::string("\")"); + } + + template <typename IteratorT> + inline std::string + parser_name(strlit<IteratorT> const &p) + { + return std::string("strlit(\"") + + std::string(p.seq.first, p.seq.last) + + std::string("\")"); + } + + inline std::string + parser_name(nothing_parser const&) + { + return std::string("nothing"); + } + + inline std::string + parser_name(epsilon_parser const&) + { + return std::string("epsilon"); + } + + inline std::string + parser_name(anychar_parser const&) + { + return std::string("anychar"); + } + + inline std::string + parser_name(alnum_parser const&) + { + return std::string("alnum"); + } + + inline std::string + parser_name(alpha_parser const&) + { + return std::string("alpha"); + } + + inline std::string + parser_name(cntrl_parser const&) + { + return std::string("cntrl"); + } + + inline std::string + parser_name(digit_parser const&) + { + return std::string("digit"); + } + + inline std::string + parser_name(graph_parser const&) + { + return std::string("graph"); + } + + inline std::string + parser_name(lower_parser const&) + { + return std::string("lower"); + } + + inline std::string + parser_name(print_parser const&) + { + return std::string("print"); + } + + inline std::string + parser_name(punct_parser const&) + { + return std::string("punct"); + } + + inline std::string + parser_name(blank_parser const&) + { + return std::string("blank"); + } + + inline std::string + parser_name(space_parser const&) + { + return std::string("space"); + } + + inline std::string + parser_name(upper_parser const&) + { + return std::string("upper"); + } + + inline std::string + parser_name(xdigit_parser const&) + { + return std::string("xdigit"); + } + + inline std::string + parser_name(eol_parser const&) + { + return std::string("eol"); + } + + inline std::string + parser_name(end_parser const&) + { + return std::string("end"); + } + +/////////////////////////////////////////////////////////////////////////////// +// from rule.hpp + namespace impl { + struct node_registry + { + typedef std::pair<std::string, bool> rule_info; + typedef std::map<void const *, rule_info> rule_infos; + + std::string find_node(void const *r) + { + rule_infos::const_iterator cit = infos.find(r); + if (cit != infos.end()) + return (*cit).second.first; + return std::string("<unknown>"); + } + + bool trace_node(void const *r) + { + rule_infos::const_iterator cit = infos.find(r); + if (cit != infos.end()) + return (*cit).second.second; + return BOOST_SPIRIT_DEBUG_TRACENODE; + } + + bool register_node(void const *r, char const *name_to_register, + bool trace_node) + { + if (infos.find(r) != infos.end()) + return false; + + return infos.insert(rule_infos::value_type(r, + rule_info(std::string(name_to_register), trace_node)) + ).second; + } + + bool unregister_node(void const *r) + { + if (infos.find(r) == infos.end()) + return false; + return (1 == infos.erase(r)); + } + + private: + rule_infos infos; + }; + + inline node_registry & + get_node_registry() + { + static node_registry node_infos; + return node_infos; + } + } // namespace impl + + template< + typename DerivedT, typename EmbedT, + typename T0, typename T1, typename T2 + > + inline std::string + parser_name(impl::rule_base<DerivedT, EmbedT, T0, T1, T2> const& p) + { + return std::string("rule_base") + + std::string("(") + + impl::get_node_registry().find_node(&p) + + std::string(")"); + } + + template<typename T0, typename T1, typename T2> + inline std::string + parser_name(rule<T0, T1, T2> const& p) + { + return std::string("rule") + + std::string("(") + + impl::get_node_registry().find_node(&p) + + std::string(")"); + } + +/////////////////////////////////////////////////////////////////////////////// +// from subrule.hpp + template <typename FirstT, typename RestT> + inline std::string + parser_name(subrule_list<FirstT, RestT> const &p) + { + return std::string("subrule_list") + + std::string("(") + + impl::get_node_registry().find_node(&p) + + std::string(")"); + } + + template <int ID, typename DefT, typename ContextT> + inline std::string + parser_name(subrule_parser<ID, DefT, ContextT> const &p) + { + return std::string("subrule_parser") + + std::string("(") + + impl::get_node_registry().find_node(&p) + + std::string(")"); + } + + template <int ID, typename ContextT> + inline std::string + parser_name(subrule<ID, ContextT> const &p) + { + BOOST_SPIRIT_SSTREAM stream; + stream << ID; + return std::string("subrule<") + + BOOST_SPIRIT_GETSTRING(stream) + + std::string(">(") + + impl::get_node_registry().find_node(&p) + + std::string(")"); + } + +/////////////////////////////////////////////////////////////////////////////// +// from grammar.hpp + template <typename DerivedT, typename ContextT> + inline std::string + parser_name(grammar<DerivedT, ContextT> const& p) + { + return std::string("grammar") + + std::string("(") + + impl::get_node_registry().find_node(&p) + + std::string(")"); + } + +/////////////////////////////////////////////////////////////////////////////// +// decide, if a node is to be traced or not + template< + typename DerivedT, typename EmbedT, + typename T0, typename T1, typename T2 + > + inline bool + trace_parser(impl::rule_base<DerivedT, EmbedT, T0, T1, T2> + const& p) + { + return impl::get_node_registry().trace_node(&p); + } + + template<typename T0, typename T1, typename T2> + inline bool + trace_parser(rule<T0, T1, T2> const& p) + { + return impl::get_node_registry().trace_node(&p); + } + + template <typename DerivedT, typename ContextT> + inline bool + trace_parser(grammar<DerivedT, ContextT> const& p) + { + return impl::get_node_registry().trace_node(&p); + } + + template <typename DerivedT, int N, typename ContextT> + inline bool + trace_parser(impl::entry_grammar<DerivedT, N, ContextT> const& p) + { + return impl::get_node_registry().trace_node(&p); + } + + template <int ID, typename ContextT> + bool + trace_parser(subrule<ID, ContextT> const& p) + { + return impl::get_node_registry().trace_node(&p); + } + + template <typename ParserT, typename ActorTupleT> + bool + trace_parser(init_closure_parser<ParserT, ActorTupleT> const& p) + { + return impl::get_node_registry().trace_node(&p); + } + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#undef BOOST_SPIRIT_SSTREAM +#undef BOOST_SPIRIT_GETSTRING + +#endif // defined(BOOST_SPIRIT_DEBUG) + +#endif // !defined(BOOST_SPIRIT_PARSER_NAMES_IPP) diff --git a/boost/spirit/home/classic/debug/minimal.hpp b/boost/spirit/home/classic/debug/minimal.hpp new file mode 100644 index 0000000000..0cb42644aa --- /dev/null +++ b/boost/spirit/home/classic/debug/minimal.hpp @@ -0,0 +1,81 @@ +/*============================================================================= + Copyright (c) 2001-2003 Joel de Guzman + Copyright (c) 2002-2003 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_MINIMAL_DEBUG_HPP) +#define BOOST_SPIRIT_MINIMAL_DEBUG_HPP + +#if !defined(BOOST_SPIRIT_DEBUG_MAIN_HPP) +#error "You must include boost/spirit/debug.hpp, not boost/spirit/debug/minimal.hpp" +#endif +/////////////////////////////////////////////////////////////////////////////// +// +// Minimum debugging tools support +// +/////////////////////////////////////////////////////////////////////////////// +#if !defined(BOOST_SPIRIT_DEBUG_OUT) +#define BOOST_SPIRIT_DEBUG_OUT std::cout +#endif + +/////////////////////////////////////////////////////////////////////////// +// +// BOOST_SPIRIT_DEBUG_FLAGS controls the level of diagnostics printed +// +/////////////////////////////////////////////////////////////////////////// +#if !defined(BOOST_SPIRIT_DEBUG_FLAGS_NONE) +#define BOOST_SPIRIT_DEBUG_FLAGS_NONE 0x0000 // no diagnostics at all +#endif + +#if !defined(BOOST_SPIRIT_DEBUG_FLAGS_MAX) +#define BOOST_SPIRIT_DEBUG_FLAGS_MAX 0xFFFF // print maximal diagnostics +#endif + +#if !defined(BOOST_SPIRIT_DEBUG_FLAGS) +#define BOOST_SPIRIT_DEBUG_FLAGS BOOST_SPIRIT_DEBUG_FLAGS_MAX +#endif + +#if !defined(BOOST_SPIRIT_DEBUG_PRINT_SOME) +#define BOOST_SPIRIT_DEBUG_PRINT_SOME 20 +#endif + +#if !defined(BOOST_SPIRIT_DEBUG_RULE) +#define BOOST_SPIRIT_DEBUG_RULE(r) +#endif // !defined(BOOST_SPIRIT_DEBUG_RULE) + +#if !defined(BOOST_SPIRIT_DEBUG_NODE) +#define BOOST_SPIRIT_DEBUG_NODE(r) +#endif // !defined(BOOST_SPIRIT_DEBUG_NODE) + +#if !defined(BOOST_SPIRIT_DEBUG_GRAMMAR) +#define BOOST_SPIRIT_DEBUG_GRAMMAR(r) +#endif // !defined(BOOST_SPIRIT_DEBUG_GRAMMAR) + +#if !defined(BOOST_SPIRIT_DEBUG_TRACE_RULE) +#define BOOST_SPIRIT_DEBUG_TRACE_RULE(r, t) +#endif // !defined(BOOST_SPIRIT_DEBUG_TRACE_RULE) + +#if !defined(BOOST_SPIRIT_DEBUG_TRACE_NODE) +#define BOOST_SPIRIT_DEBUG_TRACE_NODE(r, t) +#endif // !defined(BOOST_SPIRIT_DEBUG_TRACE_NODE) + +#if !defined(BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR) +#define BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR(r, t) +#endif // !defined(BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR) + +#if !defined(BOOST_SPIRIT_DEBUG_TRACE_RULE_NAME) +#define BOOST_SPIRIT_DEBUG_TRACE_RULE_NAME(r, n, t) +#endif // !defined(BOOST_SPIRIT_DEBUG_TRACE_RULE_NAME) + +#if !defined(BOOST_SPIRIT_DEBUG_TRACE_NODE_NAME) +#define BOOST_SPIRIT_DEBUG_TRACE_NODE_NAME(r, n, t) +#endif // !defined(BOOST_SPIRIT_DEBUG_TRACE_NODE_NAME) + +#if !defined(BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME) +#define BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(r, n, t) +#endif // !defined(BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME) + +#endif // !defined(BOOST_SPIRIT_MINIMAL_DEBUG_HPP) diff --git a/boost/spirit/home/classic/debug/parser_names.hpp b/boost/spirit/home/classic/debug/parser_names.hpp new file mode 100644 index 0000000000..edd17cc004 --- /dev/null +++ b/boost/spirit/home/classic/debug/parser_names.hpp @@ -0,0 +1,254 @@ +/*============================================================================= + Copyright (c) 2001-2003 Joel de Guzman + Copyright (c) 2002-2003 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_PARSER_NAMES_HPP) +#define BOOST_SPIRIT_PARSER_NAMES_HPP + +#if defined(BOOST_SPIRIT_DEBUG) + +////////////////////////////////// +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// +// Declaration of helper functions, which return the name of a concrete +// parser instance. The functions are specialized on the parser types. The +// functions declared in this file are for the predefined parser types from +// the Spirit core library only, so additional functions might be provided as +// needed. +// +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// from actions.hpp + template <typename ParserT, typename ActionT> + std::string + parser_name(action<ParserT, ActionT> const& p); + +/////////////////////////////////////////////////////////////////////////////// +// from directives.hpp + template <typename ParserT> + std::string + parser_name(contiguous<ParserT> const& p); + + template <typename ParserT> + std::string + parser_name(inhibit_case<ParserT> const& p); + + template <typename A, typename B> + std::string + parser_name(longest_alternative<A, B> const& p); + + template <typename A, typename B> + std::string + parser_name(shortest_alternative<A, B> const& p); + +/////////////////////////////////////////////////////////////////////////////// +// from grammar.hpp + template <typename DerivedT, typename ContextT> + std::string + parser_name(grammar<DerivedT, ContextT> const& p); + +/////////////////////////////////////////////////////////////////////////////// +// from numerics.hpp + template <typename T, int Radix, unsigned MinDigits, int MaxDigits> + std::string + parser_name(uint_parser<T, Radix, MinDigits, MaxDigits> const& p); + + template <typename T, int Radix, unsigned MinDigits, int MaxDigits> + std::string + parser_name(int_parser<T, Radix, MinDigits, MaxDigits> const& p); + + template <typename T, typename RealPoliciesT> + std::string + parser_name(real_parser<T, RealPoliciesT> const& p); + +/////////////////////////////////////////////////////////////////////////////// +// from operators.hpp + template <typename A, typename B> + std::string + parser_name(sequence<A, B> const& p); + + template <typename A, typename B> + std::string + parser_name(sequential_or<A, B> const& p); + + template <typename A, typename B> + std::string + parser_name(alternative<A, B> const& p); + + template <typename A, typename B> + std::string + parser_name(intersection<A, B> const& p); + + template <typename A, typename B> + std::string + parser_name(difference<A, B> const& p); + + template <typename A, typename B> + std::string + parser_name(exclusive_or<A, B> const& p); + + template <typename S> + std::string + parser_name(optional<S> const& p); + + template <typename S> + std::string + parser_name(kleene_star<S> const& p); + + template <typename S> + std::string + parser_name(positive<S> const& p); + +/////////////////////////////////////////////////////////////////////////////// +// from parser.hpp + template <typename DerivedT> + std::string + parser_name(parser<DerivedT> const& p); + +/////////////////////////////////////////////////////////////////////////////// +// from primitives.hpp + template <typename DerivedT> + std::string + parser_name(char_parser<DerivedT> const &p); + + template <typename CharT> + std::string + parser_name(chlit<CharT> const &p); + + template <typename CharT> + std::string + parser_name(range<CharT> const &p); + + template <typename IteratorT> + std::string + parser_name(chseq<IteratorT> const &p); + + template <typename IteratorT> + std::string + parser_name(strlit<IteratorT> const &p); + + std::string + parser_name(nothing_parser const &p); + + std::string + parser_name(epsilon_parser const &p); + + std::string + parser_name(anychar_parser const &p); + + std::string + parser_name(alnum_parser const &p); + + std::string + parser_name(alpha_parser const &p); + + std::string + parser_name(cntrl_parser const &p); + + std::string + parser_name(digit_parser const &p); + + std::string + parser_name(graph_parser const &p); + + std::string + parser_name(lower_parser const &p); + + std::string + parser_name(print_parser const &p); + + std::string + parser_name(punct_parser const &p); + + std::string + parser_name(blank_parser const &p); + + std::string + parser_name(space_parser const &p); + + std::string + parser_name(upper_parser const &p); + + std::string + parser_name(xdigit_parser const &p); + + std::string + parser_name(eol_parser const &p); + + std::string + parser_name(end_parser const &p); + +/////////////////////////////////////////////////////////////////////////////// +// from rule.hpp + template<typename T0, typename T1, typename T2> + std::string + parser_name(rule<T0, T1, T2> const& p); + +/////////////////////////////////////////////////////////////////////////////// +// from subrule.hpp + template <typename FirstT, typename RestT> + std::string + parser_name(subrule_list<FirstT, RestT> const &p); + + template <int ID, typename DefT, typename ContextT> + std::string + parser_name(subrule_parser<ID, DefT, ContextT> const &p); + + template <int ID, typename ContextT> + std::string + parser_name(subrule<ID, ContextT> const &p); + +/////////////////////////////////////////////////////////////////////////////// +// from chset.hpp + +/////////////////////////////////////////////////////////////////////////////// +// +// Decide, if a node is to be traced or not +// +/////////////////////////////////////////////////////////////////////////////// + template< + typename DerivedT, typename EmbedT, + typename T0, typename T1, typename T2 + > + bool + trace_parser(impl::rule_base<DerivedT, EmbedT, T0, T1, T2> + const& p); + + template <typename DerivedT, typename ContextT> + bool + trace_parser(grammar<DerivedT, ContextT> const& p); + + template <int ID, typename ContextT> + bool + trace_parser(subrule<ID, ContextT> const& p); + + template <typename ParserT, typename ActorTupleT> + struct init_closure_parser; + + template <typename ParserT, typename ActorTupleT> + bool + trace_parser(init_closure_parser<ParserT, ActorTupleT> const& p); + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +////////////////////////////////// +#include <boost/spirit/home/classic/debug/impl/parser_names.ipp> + +#endif // defined(BOOST_SPIRIT_DEBUG) + +#endif // !defined(BOOST_SPIRIT_PARSER_NAMES_HPP) diff --git a/boost/spirit/home/classic/debug/typeof.hpp b/boost/spirit/home/classic/debug/typeof.hpp new file mode 100644 index 0000000000..c764d318b0 --- /dev/null +++ b/boost/spirit/home/classic/debug/typeof.hpp @@ -0,0 +1,37 @@ +/*============================================================================= + Copyright (c) 2006 Tobias Schwinger + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_DEBUG_TYPEOF_HPP) +#define BOOST_SPIRIT_DEBUG_TYPEOF_HPP + +#include <boost/typeof/typeof.hpp> + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/typeof.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + // debug_node.hpp + template<typename ContextT> struct parser_context_linker; + template<typename ScannerT> struct scanner_context_linker; + template<typename ContextT> struct closure_context_linker; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() + +// debug_node.hpp +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::parser_context_linker,1) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::scanner_context_linker,1) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::closure_context_linker,1) + +#endif + diff --git a/boost/spirit/home/classic/dynamic.hpp b/boost/spirit/home/classic/dynamic.hpp new file mode 100644 index 0000000000..41ed74f788 --- /dev/null +++ b/boost/spirit/home/classic/dynamic.hpp @@ -0,0 +1,30 @@ +/*============================================================================= + Copyright (c) 2002-2003 Joel de Guzman + Copyright (c) 2002 Juan Carlos Arevalo-Baeza + Copyright (c) 2002-2003 Martin Wille + 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_DYNAMIC_HPP +#define BOOST_SPIRIT_DYNAMIC_HPP + +#include <boost/spirit/home/classic/version.hpp> + +/////////////////////////////////////////////////////////////////////////////// +// +// Master header for Spirit.Dynamic +// +/////////////////////////////////////////////////////////////////////////////// +#include <boost/spirit/home/classic/dynamic/if.hpp> +#include <boost/spirit/home/classic/dynamic/for.hpp> +#include <boost/spirit/home/classic/dynamic/while.hpp> +#include <boost/spirit/home/classic/dynamic/lazy.hpp> +#include <boost/spirit/home/classic/dynamic/stored_rule.hpp> +#include <boost/spirit/home/classic/dynamic/rule_alias.hpp> +#include <boost/spirit/home/classic/dynamic/select.hpp> +#include <boost/spirit/home/classic/dynamic/switch.hpp> + +//////////////////////////////////////////////////////////////////////////////// +#endif // BOOST_SPIRIT_DYNAMIC_HPP diff --git a/boost/spirit/home/classic/dynamic/for.hpp b/boost/spirit/home/classic/dynamic/for.hpp new file mode 100644 index 0000000000..45edd6a968 --- /dev/null +++ b/boost/spirit/home/classic/dynamic/for.hpp @@ -0,0 +1,187 @@ +/*============================================================================= + Copyright (c) 2002-2003 Joel de Guzman + Copyright (c) 2002-2003 Martin Wille + 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_FOR_HPP +#define BOOST_SPIRIT_FOR_HPP +//////////////////////////////////////////////////////////////////////////////// +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/core/composite/composite.hpp> +#include <boost/spirit/home/classic/dynamic/impl/conditions.ipp> + +//////////////////////////////////////////////////////////////////////////////// + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + namespace impl + { + + template <typename FuncT> + struct for_functor + { + typedef typename boost::call_traits<FuncT>::param_type param_t; + + for_functor(param_t f) : func(f) {} + for_functor() {} + FuncT func; + }; + + template <typename InitF> + struct for_init_functor : for_functor<InitF> + { + typedef for_functor<InitF> base_t; + typedef typename base_t::param_t param_t; + + for_init_functor(param_t f) : base_t(f) {} + for_init_functor() : base_t() {} + void init() const { /*return*/ this->func(); } + }; + + template <typename StepF> + struct for_step_functor : for_functor<StepF> + { + typedef for_functor<StepF> base_t; + typedef typename base_t::param_t param_t; + + for_step_functor(param_t f) : base_t(f) {} + for_step_functor() : base_t() {} + void step() const { /*return*/ this->func(); } + }; + + ////////////////////////////////// + // for_parser + template + < + typename InitF, typename CondT, typename StepF, + typename ParsableT + > + struct for_parser + : private for_init_functor<InitF> + , private for_step_functor<StepF> + , private condition_evaluator<typename as_parser<CondT>::type> + , public unary + < + typename as_parser<ParsableT>::type, + parser< for_parser<InitF, CondT, StepF, ParsableT> > + > + { + typedef for_parser<InitF, CondT, StepF, ParsableT> self_t; + typedef as_parser<CondT> cond_as_parser_t; + typedef typename cond_as_parser_t::type condition_t; + typedef condition_evaluator<condition_t> eval_t; + typedef as_parser<ParsableT> as_parser_t; + typedef typename as_parser_t::type parser_t; + typedef unary< parser_t, parser< self_t > > base_t; + + + ////////////////////////////// + // constructor, saves init, condition and step functors + // for later use the parse member function + for_parser + ( + InitF const &i, CondT const &c, StepF const &s, + ParsableT const &p + ) + : for_init_functor<InitF>(i) + , for_step_functor<StepF>(s) + , eval_t(cond_as_parser_t::convert(c)) + , base_t(as_parser_t::convert(p)) + { } + + for_parser() + : for_init_functor<InitF>() + , for_step_functor<StepF>() + , eval_t() + , base_t() + {} + + ////////////////////////////// + // parse member function + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const &scan) const + { + typedef typename parser_result<self_t, ScannerT>::type + result_t; + typedef typename parser_result<parser_t, ScannerT>::type + body_result_t; + + typename ScannerT::iterator_t save(scan.first); + + std::size_t length = 0; + int eval_length = 0; + + this->init(); + while ((eval_length = this->evaluate(scan))>=0) + { + length += eval_length; + body_result_t tmp(this->subject().parse(scan)); + if (tmp) + { + length+=tmp.length(); + } + else + { + return scan.no_match(); + } + this->step(); + } + + BOOST_SPIRIT_CLASSIC_NS::nil_t attr; + return scan.create_match + (length, attr, save, scan.first); + } + }; + + ////////////////////////////////// + // for_parser_gen generates takes the body parser in brackets + // and returns the for_parser + template <typename InitF, typename CondT, typename StepF> + struct for_parser_gen + { + for_parser_gen(InitF const &i, CondT const &c, StepF const &s) + : init(i) + , condition(c) + , step(s) + {} + + template <typename ParsableT> + for_parser<InitF, CondT, StepF, ParsableT> + operator[](ParsableT const &p) const + { + return for_parser<InitF, CondT, StepF, ParsableT> + (init, condition, step, p); + } + + InitF const &init; + CondT const &condition; + StepF const &step; + }; + } // namespace impl + + ////////////////////////////// + // for_p, returns for-parser generator + // Usage: spirit::for_p(init-ftor, condition, step-ftor)[body] + template + < + typename InitF, typename ConditionT, typename StepF + > + impl::for_parser_gen<InitF, ConditionT, StepF> + for_p(InitF const &init_f, ConditionT const &condition, StepF const &step_f) + { + return impl::for_parser_gen<InitF, ConditionT, StepF> + (init_f, condition, step_f); + } + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif // BOOST_SPIRIT_FOR_HPP diff --git a/boost/spirit/home/classic/dynamic/if.hpp b/boost/spirit/home/classic/dynamic/if.hpp new file mode 100644 index 0000000000..b7fbb77120 --- /dev/null +++ b/boost/spirit/home/classic/dynamic/if.hpp @@ -0,0 +1,229 @@ +/*============================================================================= + Copyright (c) 2002-2003 Joel de Guzman + Copyright (c) 2002 Juan Carlos Arevalo-Baeza + Copyright (c) 2002-2003 Martin Wille + 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_IF_HPP +#define BOOST_SPIRIT_IF_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/core/composite/composite.hpp> +#include <boost/spirit/home/classic/dynamic/impl/conditions.ipp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + namespace impl { + + ////////////////////////////////// + // if-else-parser, holds two alternative parsers and a conditional functor + // that selects between them. + template <typename ParsableTrueT, typename ParsableFalseT, typename CondT> + struct if_else_parser + : public condition_evaluator<typename as_parser<CondT>::type> + , public binary + < + typename as_parser<ParsableTrueT>::type, + typename as_parser<ParsableFalseT>::type, + parser< if_else_parser<ParsableTrueT, ParsableFalseT, CondT> > + > + { + typedef if_else_parser<ParsableTrueT, ParsableFalseT, CondT> self_t; + + typedef as_parser<ParsableTrueT> as_parser_true_t; + typedef as_parser<ParsableFalseT> as_parser_false_t; + typedef typename as_parser_true_t::type parser_true_t; + typedef typename as_parser_false_t::type parser_false_t; + typedef as_parser<CondT> cond_as_parser_t; + typedef typename cond_as_parser_t::type condition_t; + + typedef binary<parser_true_t, parser_false_t, parser<self_t> > base_t; + typedef condition_evaluator<condition_t> eval_t; + + if_else_parser + ( + ParsableTrueT const& p_true, + ParsableFalseT const& p_false, + CondT const& cond_ + ) + : eval_t(cond_as_parser_t::convert(cond_)) + , base_t + ( + as_parser_true_t::convert(p_true), + as_parser_false_t::convert(p_false) + ) + { } + + template <typename ScannerT> + struct result + { + typedef typename match_result<ScannerT, nil_t>::type type; + }; + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename parser_result + <parser_true_t, ScannerT>::type then_result_t; + typedef typename parser_result + <parser_false_t, ScannerT>::type else_result_t; + + typename ScannerT::iterator_t const save(scan.first); + + std::ptrdiff_t length = this->evaluate(scan); + if (length >= 0) + { + then_result_t then_result(this->left().parse(scan)); + if (then_result) + { + length += then_result.length(); + return scan.create_match(std::size_t(length), nil_t(), save, scan.first); + } + } + else + { + else_result_t else_result(this->right().parse(scan)); + if (else_result) + { + length = else_result.length(); + return scan.create_match(std::size_t(length), nil_t(), save, scan.first); + } + } + return scan.no_match(); + } + }; + + ////////////////////////////////// + // if-else-parser generator, takes the false-parser in brackets + // and returns the if-else-parser. + template <typename ParsableTrueT, typename CondT> + struct if_else_parser_gen + { + if_else_parser_gen(ParsableTrueT const& p_true_, CondT const& cond_) + : p_true(p_true_) + , cond(cond_) {} + + template <typename ParsableFalseT> + if_else_parser + < + ParsableTrueT, + ParsableFalseT, + CondT + > + operator[](ParsableFalseT const& p_false) const + { + return if_else_parser<ParsableTrueT, ParsableFalseT, CondT> + ( + p_true, + p_false, + cond + ); + } + + ParsableTrueT const &p_true; + CondT const &cond; + }; + + ////////////////////////////////// + // if-parser, conditionally runs a parser is a functor condition is true. + // If the condition is fales, it fails the parse. + // It can optionally become an if-else-parser through the member else_p. + template <typename ParsableT, typename CondT> + struct if_parser + : public condition_evaluator<typename as_parser<CondT>::type> + , public unary + < + typename as_parser<ParsableT>::type, + parser<if_parser<ParsableT, CondT> > > + { + typedef if_parser<ParsableT, CondT> self_t; + typedef as_parser<ParsableT> as_parser_t; + typedef typename as_parser_t::type parser_t; + + typedef as_parser<CondT> cond_as_parser_t; + typedef typename cond_as_parser_t::type condition_t; + typedef condition_evaluator<condition_t> eval_t; + typedef unary<parser_t, parser<self_t> > base_t; + + if_parser(ParsableT const& p, CondT const& cond_) + : eval_t(cond_as_parser_t::convert(cond_)) + , base_t(as_parser_t::convert(p)) + , else_p(p, cond_) + {} + + template <typename ScannerT> + struct result + { + typedef typename match_result<ScannerT, nil_t>::type type; + }; + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename parser_result<parser_t, ScannerT>::type t_result_t; + typename ScannerT::iterator_t const save(scan.first); + + std::ptrdiff_t length = this->evaluate(scan); + if (length >= 0) + { + t_result_t then_result(this->subject().parse(scan)); + if (then_result) + { + length += then_result.length(); + return scan.create_match(std::size_t(length), nil_t(), save, scan.first); + } + return scan.no_match(); + } + return scan.empty_match(); + } + + if_else_parser_gen<ParsableT, CondT> else_p; + }; + + ////////////////////////////////// + // if-parser generator, takes the true-parser in brackets and returns the + // if-parser. + template <typename CondT> + struct if_parser_gen + { + if_parser_gen(CondT const& cond_) : cond(cond_) {} + + template <typename ParsableT> + if_parser + < + ParsableT, + CondT + > + operator[](ParsableT const& subject) const + { + return if_parser<ParsableT, CondT>(subject, cond); + } + + CondT const &cond; + }; + +} // namespace impl + +////////////////////////////////// +// if_p function, returns "if" parser generator + +template <typename CondT> +impl::if_parser_gen<CondT> +if_p(CondT const& cond) +{ + return impl::if_parser_gen<CondT>(cond); +} + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif // BOOST_SPIRIT_IF_HPP diff --git a/boost/spirit/home/classic/dynamic/impl/conditions.ipp b/boost/spirit/home/classic/dynamic/impl/conditions.ipp new file mode 100644 index 0000000000..713958463c --- /dev/null +++ b/boost/spirit/home/classic/dynamic/impl/conditions.ipp @@ -0,0 +1,104 @@ +/*============================================================================= + Copyright (c) 2002-2003 Martin Wille + 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_SPIRIT_CONDITIONS_IPP +#define BOOST_SPIRIT_CONDITIONS_IPP + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/spirit/home/classic/meta/parser_traits.hpp> +#include <boost/spirit/home/classic/core/composite/epsilon.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + namespace impl { + +/////////////////////////////////////////////////////////////////////////////// +// +// condition evaluation +// +/////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////// + // condition_parser_selector, decides which parser to use for a condition + // If the template argument is a parser then that parser is used. + // If the template argument is a functor then a condition parser using + // the functor is chosen + + template <typename T> struct embed_t_accessor + { + typedef typename T::embed_t type; + }; + +#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 + template <> struct embed_t_accessor<int> + { + typedef int type; + }; +#endif + + template <typename ConditionT> + struct condition_parser_selector + { + typedef + typename mpl::if_< + is_parser<ConditionT>, + ConditionT, + condition_parser<ConditionT> + >::type + type; + + typedef typename embed_t_accessor<type>::type embed_t; + }; + + ////////////////////////////////// + // condition_evaluator, uses a parser to check wether a condition is met + // takes a parser or a functor that can be evaluated in boolean context + // as template parameter. + + // JDG 4-15-03 refactored + template <typename ConditionT> + struct condition_evaluator + { + typedef condition_parser_selector<ConditionT> selector_t; + typedef typename selector_t::type selected_t; + typedef typename selector_t::embed_t cond_embed_t; + + typedef typename boost::call_traits<cond_embed_t>::param_type + param_t; + + condition_evaluator(param_t s) : cond(s) {} + + ///////////////////////////// + // evaluate, checks wether condition is met + // returns length of a match or a negative number for no-match + template <typename ScannerT> + std::ptrdiff_t + evaluate(ScannerT const &scan) const + { + typedef typename ScannerT::iterator_t iterator_t; + typedef typename parser_result<selected_t, ScannerT>::type cres_t; + iterator_t save(scan.first); + cres_t result = cond.parse(scan); + if (!result) // reset the position if evaluation + scan.first = save; // fails. + return result.length(); + } + + cond_embed_t cond; + }; + +/////////////////////////////////////////////////////////////////////////////// + } // namespace impl + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#endif diff --git a/boost/spirit/home/classic/dynamic/impl/select.ipp b/boost/spirit/home/classic/dynamic/impl/select.ipp new file mode 100644 index 0000000000..531421079d --- /dev/null +++ b/boost/spirit/home/classic/dynamic/impl/select.ipp @@ -0,0 +1,120 @@ +/*============================================================================= + Copyright (c) 2003 Hartmut Kaiser + 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_SPIRIT_SELECT_IPP +#define BOOST_SPIRIT_SELECT_IPP + +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/core/composite/composite.hpp> +#include <boost/spirit/home/classic/meta/as_parser.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +namespace impl { + +/////////////////////////////////////////////////////////////////////////////// +template <typename ParserT> +struct as_embedded_parser : public as_parser<ParserT> +{ + typedef typename as_parser<ParserT>::type::derived_t::embed_t type; +}; + +/////////////////////////////////////////////////////////////////////////////// + +// no implementation here to catch unknown BehaviourT template arguments +template <typename ResultT, typename BehaviourT> +struct select_match_gen; + +// implementation for the select_default_no_fail behaviour +template <typename ResultT> +struct select_match_gen<ResultT, select_default_no_fail> { + + template <typename ScannerT> + static ResultT + do_ (ScannerT const &scan) + { + return scan.create_match(0, -1, scan.first, scan.first); + } +}; + +// implementation for the select_default_fail behaviour +template <typename ResultT> +struct select_match_gen<ResultT, select_default_fail> { + + template <typename ScannerT> + static ResultT + do_ (ScannerT const &scan) + { + return scan.no_match(); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +template <int N, typename ResultT, typename TupleT, typename BehaviourT> +struct parse_tuple_element { + + BOOST_STATIC_CONSTANT(int, index = (TupleT::length - N)); + + template <typename ScannerT> + static ResultT + do_(TupleT const &t, ScannerT const &scan) + { + typedef typename ::phoenix::tuple_element<index, TupleT>::type parser_t; + typedef typename ScannerT::iterator_t iterator_t; + typedef typename parser_result<parser_t, ScannerT>::type result_t; + + iterator_t save(scan.first); + result_t result(t[::phoenix::tuple_index<index>()].parse(scan)); + + if (result) { + return scan.create_match(result.length(), TupleT::length - N, + save, scan.first); + } + scan.first = save; // reset the input stream + return parse_tuple_element<N-1, ResultT, TupleT, BehaviourT>:: + do_(t, scan); + } +}; + +template <typename ResultT, typename TupleT, typename BehaviourT> +struct parse_tuple_element<1, ResultT, TupleT, BehaviourT> { + + BOOST_STATIC_CONSTANT(int, index = (TupleT::length - 1)); + + template <typename ScannerT> + static ResultT + do_(TupleT const &t, ScannerT const &scan) + { + typedef typename ::phoenix::tuple_element<index, TupleT>::type parser_t; + typedef typename ScannerT::iterator_t iterator_t; + typedef typename parser_result<parser_t, ScannerT>::type result_t; + + iterator_t save(scan.first); + result_t result(t[::phoenix::tuple_index<index>()].parse(scan)); + + if (result) { + return scan.create_match(result.length(), TupleT::length - 1, + save, scan.first); + } + scan.first = save; // reset the input stream + return select_match_gen<ResultT, BehaviourT>::do_(scan); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +} // namespace impl + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#endif // BOOST_SPIRIT_SELECT_IPP diff --git a/boost/spirit/home/classic/dynamic/impl/switch.ipp b/boost/spirit/home/classic/dynamic/impl/switch.ipp new file mode 100644 index 0000000000..ffaa3ebb8b --- /dev/null +++ b/boost/spirit/home/classic/dynamic/impl/switch.ipp @@ -0,0 +1,574 @@ +/*============================================================================= + Copyright (c) 2003 Hartmut Kaiser + 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_SPIRIT_SWITCH_IPP +#define BOOST_SPIRIT_SWITCH_IPP + +#include <boost/mpl/if.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/static_assert.hpp> + +#include <boost/preprocessor/cat.hpp> +#include <boost/preprocessor/inc.hpp> +#include <boost/preprocessor/repeat.hpp> +#include <boost/preprocessor/repeat_from_to.hpp> + +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/core/primitives/primitives.hpp> +#include <boost/spirit/home/classic/core/composite/composite.hpp> +#include <boost/spirit/home/classic/meta/as_parser.hpp> + +#include <boost/spirit/home/classic/phoenix/actor.hpp> +#include <boost/spirit/home/classic/phoenix/tuples.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +// forward declaration +template <int N, typename ParserT, bool IsDefault> struct case_parser; + +/////////////////////////////////////////////////////////////////////////////// +namespace impl { + +/////////////////////////////////////////////////////////////////////////////// +// parse helper functions +template <typename ParserT, typename ScannerT> +inline typename parser_result<ParserT, ScannerT>::type +delegate_parse(ParserT const &p, ScannerT const &scan, + typename ScannerT::iterator_t const save) +{ + typedef typename parser_result<ParserT, ScannerT>::type result_t; + + result_t result (p.subject().parse(scan)); + if (!result) + scan.first = save; + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +// General default case handling (no default_p case branch given). +// First try to match the current parser node (if the condition value is +// matched) and, if that fails, return a no_match +template <int N, bool IsDefault, bool HasDefault> +struct default_delegate_parse { + + template < + typename ParserT, typename DefaultT, + typename ValueT, typename ScannerT + > + static typename parser_result<ParserT, ScannerT>::type + parse (ValueT const &value, ParserT const &p, DefaultT const &, + ScannerT const &scan, typename ScannerT::iterator_t const save) + { + if (value == N) + return delegate_parse(p, scan, save); + return scan.no_match(); + } +}; + +// The current case parser node is the default parser. +// Ignore the given case value and try to match the given default parser. +template <int N, bool HasDefault> +struct default_delegate_parse<N, true, HasDefault> { + + template < + typename ParserT, typename DefaultT, + typename ValueT, typename ScannerT + > + static typename parser_result<ParserT, ScannerT>::type + parse (ValueT const& /*value*/, ParserT const &, DefaultT const &d, + ScannerT const &scan, typename ScannerT::iterator_t const save) + { + // Since there is a default_p case branch defined, the corresponding + // parser shouldn't be the nothing_parser + BOOST_STATIC_ASSERT((!boost::is_same<DefaultT, nothing_parser>::value)); + return delegate_parse(d, scan, save); + } +}; + +// The current case parser node is not the default parser, but there is a +// default_p branch given inside the switch_p parser. +// First try to match the current parser node (if the condition value is +// matched) and, if that fails, match the given default_p parser. +template <int N> +struct default_delegate_parse<N, false, true> { + + template < + typename ParserT, typename DefaultT, + typename ValueT, typename ScannerT + > + static typename parser_result<ParserT, ScannerT>::type + parse (ValueT const &value, ParserT const &p, DefaultT const &d, + ScannerT const &scan, typename ScannerT::iterator_t const save) + { + // Since there is a default_p case branch defined, the corresponding + // parser shouldn't be the nothing_parser + BOOST_STATIC_ASSERT((!boost::is_same<DefaultT, nothing_parser>::value)); + if (value == N) + return delegate_parse(p, scan, save); + + return delegate_parse(d, scan, save); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// Look through the case parser chain to test, if there is a default case +// branch defined (returned by 'value'). +template <typename CaseT, bool IsSimple = CaseT::is_simple> +struct default_case; + +//////////////////////////////////////// +template <typename ResultT, bool IsDefault> +struct get_default_parser { + + template <typename ParserT> + static ResultT + get(parser<ParserT> const &p) + { + return default_case<typename ParserT::derived_t::left_t>:: + get(p.derived().left()); + } +}; + +template <typename ResultT> +struct get_default_parser<ResultT, true> { + + template <typename ParserT> + static ResultT + get(parser<ParserT> const &p) { return p.derived().right(); } +}; + +//////////////////////////////////////// +template <typename CaseT, bool IsSimple> +struct default_case { + + // The 'value' constant is true, if the current case_parser or one of its + // left siblings is a default_p generated case_parser. + BOOST_STATIC_CONSTANT(bool, value = + (CaseT::is_default || default_case<typename CaseT::left_t>::value)); + + // The 'is_epsilon' constant is true, if the current case_parser or one of + // its left siblings is a default_p generated parser with an attached + // epsilon_p (this is generated by the plain default_p). + BOOST_STATIC_CONSTANT(bool, is_epsilon = ( + (CaseT::is_default && CaseT::is_epsilon) || + default_case<typename CaseT::left_t>::is_epsilon + )); + + // The computed 'type' represents the type of the default case branch + // parser (if there is one) or nothing_parser (if there isn't any default + // case branch). + typedef typename boost::mpl::if_c< + CaseT::is_default, typename CaseT::right_embed_t, + typename default_case<typename CaseT::left_t>::type + >::type type; + + // The get function returns the parser attached to the default case branch + // (if there is one) or an instance of a nothing_parser (if there isn't + // any default case branch). + template <typename ParserT> + static type + get(parser<ParserT> const &p) + { return get_default_parser<type, CaseT::is_default>::get(p); } +}; + +//////////////////////////////////////// +template <typename ResultT, bool IsDefault> +struct get_default_parser_simple { + + template <typename ParserT> + static ResultT + get(parser<ParserT> const &p) { return p.derived(); } +}; + +template <typename ResultT> +struct get_default_parser_simple<ResultT, false> { + + template <typename ParserT> + static nothing_parser + get(parser<ParserT> const &) { return nothing_p; } +}; + +//////////////////////////////////////// +// Specialization of the default_case template for the last (leftmost) element +// of the case parser chain. +template <typename CaseT> +struct default_case<CaseT, true> { + + // The 'value' and 'is_epsilon' constant, the 'type' type and the function + // 'get' are described above. + + BOOST_STATIC_CONSTANT(bool, value = CaseT::is_default); + BOOST_STATIC_CONSTANT(bool, is_epsilon = ( + CaseT::is_default && CaseT::is_epsilon + )); + + typedef typename boost::mpl::if_c< + CaseT::is_default, CaseT, nothing_parser + >::type type; + + template <typename ParserT> + static type + get(parser<ParserT> const &p) + { return get_default_parser_simple<type, value>::get(p); } +}; + +/////////////////////////////////////////////////////////////////////////////// +// The case_chain template calculates recursivly the depth of the left +// subchain of the given case branch node. +template <typename CaseT, bool IsSimple = CaseT::is_simple> +struct case_chain { + + BOOST_STATIC_CONSTANT(int, depth = ( + case_chain<typename CaseT::left_t>::depth + 1 + )); +}; + +template <typename CaseT> +struct case_chain<CaseT, true> { + + BOOST_STATIC_CONSTANT(int, depth = 0); +}; + +/////////////////////////////////////////////////////////////////////////////// +// The chain_parser template is used to extract the type and the instance of +// a left or a right parser, burried arbitrary deep inside the case parser +// chain. +template <int Depth, typename CaseT> +struct chain_parser { + + typedef typename CaseT::left_t our_left_t; + + typedef typename chain_parser<Depth-1, our_left_t>::left_t left_t; + typedef typename chain_parser<Depth-1, our_left_t>::right_t right_t; + + static left_t + left(CaseT const &p) + { return chain_parser<Depth-1, our_left_t>::left(p.left()); } + + static right_t + right(CaseT const &p) + { return chain_parser<Depth-1, our_left_t>::right(p.left()); } +}; + +template <typename CaseT> +struct chain_parser<1, CaseT> { + + typedef typename CaseT::left_t left_t; + typedef typename CaseT::right_t right_t; + + static left_t left(CaseT const &p) { return p.left(); } + static right_t right(CaseT const &p) { return p.right(); } +}; + +template <typename CaseT> +struct chain_parser<0, CaseT>; // shouldn't be instantiated + +/////////////////////////////////////////////////////////////////////////////// +// Type computing meta function for calculating the type of the return value +// of the used conditional switch expression +template <typename TargetT, typename ScannerT> +struct condition_result { + + typedef typename TargetT::template result<ScannerT>::type type; +}; + +/////////////////////////////////////////////////////////////////////////////// +template <typename LeftT, typename RightT, bool IsDefault> +struct compound_case_parser +: public binary<LeftT, RightT, + parser<compound_case_parser<LeftT, RightT, IsDefault> > > +{ + typedef compound_case_parser<LeftT, RightT, IsDefault> self_t; + typedef binary_parser_category parser_category_t; + typedef binary<LeftT, RightT, parser<self_t> > base_t; + + BOOST_STATIC_CONSTANT(int, value = RightT::value); + BOOST_STATIC_CONSTANT(bool, is_default = IsDefault); + BOOST_STATIC_CONSTANT(bool, is_simple = false); + BOOST_STATIC_CONSTANT(bool, is_epsilon = ( + is_default && + boost::is_same<typename RightT::subject_t, epsilon_parser>::value + )); + + compound_case_parser(parser<LeftT> const &lhs, parser<RightT> const &rhs) + : base_t(lhs.derived(), rhs.derived()) + {} + + template <typename ScannerT> + struct result + { + typedef typename match_result<ScannerT, nil_t>::type type; + }; + + template <typename ScannerT, typename CondT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan, CondT const &cond) const; + + template <int N1, typename ParserT1, bool IsDefault1> + compound_case_parser< + self_t, case_parser<N1, ParserT1, IsDefault1>, IsDefault1 + > + operator, (case_parser<N1, ParserT1, IsDefault1> const &p) const + { + // If the following compile time assertion fires, you've probably used + // more than one default_p case inside the switch_p parser construct. + BOOST_STATIC_ASSERT(!default_case<self_t>::value || !IsDefault1); + + // If this compile time assertion fires, you've probably want to use + // more case_p/default_p case branches, than possible. + BOOST_STATIC_ASSERT( + case_chain<self_t>::depth < BOOST_SPIRIT_SWITCH_CASE_LIMIT + ); + + typedef case_parser<N1, ParserT1, IsDefault1> right_t; + return compound_case_parser<self_t, right_t, IsDefault1>(*this, p); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// The parse_switch::do_ functions dispatch to the correct parser, which is +// selected through the given conditional switch value. +template <int Value, int Depth, bool IsDefault> +struct parse_switch; + +/////////////////////////////////////////////////////////////////////////////// +// +// The following generates a couple of parse_switch template specializations +// with an increasing number of handled case branches (for 1..N). +// +// template <int Value, bool IsDefault> +// struct parse_switch<Value, N, IsDefault> { +// +// template <typename ParserT, typename ScannerT> +// static typename parser_result<ParserT, ScannerT>::type +// do_(ParserT const &p, ScannerT const &scan, long cond_value, +// typename ScannerT::iterator_t const &save) +// { +// typedef ParserT left_t0; +// typedef typename left_t0::left left_t1; +// ... +// +// switch (cond_value) { +// case left_tN::value: +// return delegate_parse(chain_parser< +// case_chain<ParserT>::depth, ParserT +// >::left(p), scan, save); +// ... +// case left_t1::value: +// return delegate_parse(chain_parser< +// 1, left_t1 +// >::right(p.left()), scan, save); +// +// case left_t0::value: +// default: +// typedef default_case<ParserT> default_t; +// typedef default_delegate_parse< +// Value, IsDefault, default_t::value> +// default_parse_t; +// +// return default_parse_t::parse(cond_value, p.right(), +// default_t::get(p), scan, save); +// } +// } +// }; +// +/////////////////////////////////////////////////////////////////////////////// +#define BOOST_SPIRIT_PARSE_SWITCH_TYPEDEFS(z, N, _) \ + typedef typename BOOST_PP_CAT(left_t, N)::left_t \ + BOOST_PP_CAT(left_t, BOOST_PP_INC(N)); \ + /**/ + +#define BOOST_SPIRIT_PARSE_SWITCH_CASES(z, N, _) \ + case (long)(BOOST_PP_CAT(left_t, N)::value): \ + return delegate_parse(chain_parser<N, left_t1>::right(p.left()), \ + scan, save); \ + /**/ + +#define BOOST_SPIRIT_PARSE_SWITCHES(z, N, _) \ + template <int Value, bool IsDefault> \ + struct parse_switch<Value, BOOST_PP_INC(N), IsDefault> { \ + \ + template <typename ParserT, typename ScannerT> \ + static typename parser_result<ParserT, ScannerT>::type \ + do_(ParserT const &p, ScannerT const &scan, long cond_value, \ + typename ScannerT::iterator_t const &save) \ + { \ + typedef ParserT left_t0; \ + BOOST_PP_REPEAT_FROM_TO_ ## z(0, BOOST_PP_INC(N), \ + BOOST_SPIRIT_PARSE_SWITCH_TYPEDEFS, _) \ + \ + switch (cond_value) { \ + case (long)(BOOST_PP_CAT(left_t, BOOST_PP_INC(N))::value): \ + return delegate_parse( \ + chain_parser< \ + case_chain<ParserT>::depth, ParserT \ + >::left(p), scan, save); \ + \ + BOOST_PP_REPEAT_FROM_TO_ ## z(1, BOOST_PP_INC(N), \ + BOOST_SPIRIT_PARSE_SWITCH_CASES, _) \ + \ + case (long)(left_t0::value): \ + default: \ + typedef default_case<ParserT> default_t; \ + typedef \ + default_delegate_parse<Value, IsDefault, default_t::value> \ + default_parse_t; \ + \ + return default_parse_t::parse(cond_value, p.right(), \ + default_t::get(p), scan, save); \ + } \ + } \ + }; \ + /**/ + +BOOST_PP_REPEAT(BOOST_PP_DEC(BOOST_SPIRIT_SWITCH_CASE_LIMIT), + BOOST_SPIRIT_PARSE_SWITCHES, _) + +#undef BOOST_SPIRIT_PARSE_SWITCH_TYPEDEFS +#undef BOOST_SPIRIT_PARSE_SWITCH_CASES +#undef BOOST_SPIRIT_PARSE_SWITCHES +/////////////////////////////////////////////////////////////////////////////// + +template <typename LeftT, typename RightT, bool IsDefault> +template <typename ScannerT, typename CondT> +inline typename parser_result< + compound_case_parser<LeftT, RightT, IsDefault>, ScannerT +>::type +compound_case_parser<LeftT, RightT, IsDefault>:: + parse(ScannerT const& scan, CondT const &cond) const +{ + scan.at_end(); // allow skipper to take effect + return parse_switch<value, case_chain<self_t>::depth, is_default>:: + do_(*this, scan, cond(scan), scan.first); +} + +/////////////////////////////////////////////////////////////////////////////// +// The switch condition is to be evaluated from a parser result value. +template <typename ParserT> +struct cond_functor { + + typedef cond_functor<ParserT> self_t; + + cond_functor(ParserT const &p_) + : p(p_) + {} + + template <typename ScannerT> + struct result + { + typedef typename parser_result<ParserT, ScannerT>::type::attr_t type; + }; + + template <typename ScannerT> + typename condition_result<self_t, ScannerT>::type + operator()(ScannerT const &scan) const + { + typedef typename parser_result<ParserT, ScannerT>::type result_t; + typedef typename result_t::attr_t attr_t; + + result_t result(p.parse(scan)); + return !result ? attr_t() : result.value(); + } + + typename ParserT::embed_t p; +}; + +template <typename ParserT> +struct make_cond_functor { + + typedef as_parser<ParserT> as_parser_t; + + static cond_functor<typename as_parser_t::type> + do_(ParserT const &cond) + { + return cond_functor<typename as_parser_t::type>( + as_parser_t::convert(cond)); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// The switch condition is to be evaluated from a phoenix actor +template <typename ActorT> +struct cond_actor { + + typedef cond_actor<ActorT> self_t; + + cond_actor(ActorT const &actor_) + : actor(actor_) + {} + + template <typename ScannerT> + struct result + { + typedef typename ::phoenix::actor_result<ActorT, ::phoenix::tuple<> >::type + type; + }; + + template <typename ScannerT> + typename condition_result<self_t, ScannerT>::type + operator()(ScannerT const& /*scan*/) const + { + return actor(); + } + + ActorT const &actor; +}; + +template <typename ActorT> +struct make_cond_functor< ::phoenix::actor<ActorT> > { + + static cond_actor< ::phoenix::actor<ActorT> > + do_(::phoenix::actor<ActorT> const &actor) + { + return cond_actor< ::phoenix::actor<ActorT> >(actor); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// The switch condition is to be taken directly from the input stream +struct get_next_token_cond { + + typedef get_next_token_cond self_t; + + template <typename ScannerT> + struct result + { + typedef typename ScannerT::value_t type; + }; + + template <typename ScannerT> + typename condition_result<self_t, ScannerT>::type + operator()(ScannerT const &scan) const + { + typename ScannerT::value_t val(*scan); + ++scan.first; + return val; + } +}; + +template <> +struct make_cond_functor<get_next_token_cond> { + + static get_next_token_cond + do_(get_next_token_cond const &cond) + { + return cond; + } +}; + +/////////////////////////////////////////////////////////////////////////////// +} // namespace impl + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#endif // BOOST_SPIRIT_SWITCH_IPP diff --git a/boost/spirit/home/classic/dynamic/lazy.hpp b/boost/spirit/home/classic/dynamic/lazy.hpp new file mode 100644 index 0000000000..5bc9df3af9 --- /dev/null +++ b/boost/spirit/home/classic/dynamic/lazy.hpp @@ -0,0 +1,66 @@ +/*============================================================================= + Copyright (c) 2003 Joel de Guzman + Copyright (c) 2003 Vaclav Vesely + 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_LAZY_HPP +#define BOOST_SPIRIT_LAZY_HPP + +//////////////////////////////////////////////////////////////////////////////// +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/phoenix/actor.hpp> + +//////////////////////////////////////////////////////////////////////////////// + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + //////////////////////////////////////////////////////////////////////////// + // + // lazy_parser, holds phoenix actor which returns a spirit parser. + // + //////////////////////////////////////////////////////////////////////////// + + template<class ActorT> + struct lazy_parser : parser<lazy_parser<ActorT> > + { + typedef lazy_parser<ActorT> self_t; + typedef typename ::phoenix::actor_result< + ActorT, ::phoenix::tuple<> >::plain_type actor_result_t; + + template<typename ScannerT> + struct result + { + typedef typename + parser_result<actor_result_t, ScannerT>::type + type; + }; + + lazy_parser(ActorT const& actor_) + : actor(actor_) {} + + template<typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { return actor().parse(scan); } + + ActorT actor; + }; + + ////////////////////////////// + // lazy_p, returns lazy_parser + // Usage: lazy_p(actor) + template<class ActorT> + lazy_parser<ActorT> lazy_p(ActorT const& actor) + { return lazy_parser<ActorT>(actor); } + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif // BOOST_SPIRIT_LAZY_HPP diff --git a/boost/spirit/home/classic/dynamic/rule_alias.hpp b/boost/spirit/home/classic/dynamic/rule_alias.hpp new file mode 100644 index 0000000000..de291c916d --- /dev/null +++ b/boost/spirit/home/classic/dynamic/rule_alias.hpp @@ -0,0 +1,76 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_RULE_ALIAS_HPP) +#define BOOST_SPIRIT_RULE_ALIAS_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // rule_alias class + // + /////////////////////////////////////////////////////////////////////////// + template <typename ParserT> + class rule_alias : + public parser<rule_alias<ParserT> > + { + public: + + typedef rule_alias<ParserT> self_t; + + template <typename ScannerT> + struct result + { + typedef typename parser_result<ParserT, ScannerT>::type type; + }; + + rule_alias() + : ptr(0) {} + + rule_alias(ParserT const& p) + : ptr(&p) {} + + rule_alias& + operator=(ParserT const& p) + { + ptr = &p; + return *this; + } + + template <typename ScannerT> + typename parser_result<ParserT, ScannerT>::type + parse(ScannerT const& scan) const + { + if (ptr) + return ptr->parse(scan); + else + return scan.no_match(); + } + + ParserT const& + get() const + { + BOOST_ASSERT(ptr != 0); + return *ptr; + } + + private: + + ParserT const* ptr; // hold it by pointer + }; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif diff --git a/boost/spirit/home/classic/dynamic/select.hpp b/boost/spirit/home/classic/dynamic/select.hpp new file mode 100644 index 0000000000..865b27c5e9 --- /dev/null +++ b/boost/spirit/home/classic/dynamic/select.hpp @@ -0,0 +1,245 @@ +/*============================================================================= + Copyright (c) 2003 Hartmut Kaiser + 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_SELECT_HPP +#define BOOST_SPIRIT_SELECT_HPP + +#include <boost/preprocessor/repeat.hpp> +#include <boost/preprocessor/enum.hpp> +#include <boost/preprocessor/enum_params.hpp> +#include <boost/preprocessor/enum_params_with_defaults.hpp> +#include <boost/preprocessor/inc.hpp> +#include <boost/preprocessor/cat.hpp> +#include <boost/preprocessor/facilities/intercept.hpp> + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> + +#include <boost/spirit/home/classic/phoenix/tuples.hpp> + +/////////////////////////////////////////////////////////////////////////////// +// +// Spirit predefined maximum number of possible embedded select_p parsers. +// It should NOT be greater than PHOENIX_LIMIT! +// +/////////////////////////////////////////////////////////////////////////////// +#if !defined(BOOST_SPIRIT_SELECT_LIMIT) +#define BOOST_SPIRIT_SELECT_LIMIT PHOENIX_LIMIT +#endif // !defined(BOOST_SPIRIT_SELECT_LIMIT) + +/////////////////////////////////////////////////////////////////////////////// +// +// ensure BOOST_SPIRIT_SELECT_LIMIT <= PHOENIX_LIMIT and +// BOOST_SPIRIT_SELECT_LIMIT > 0 +// BOOST_SPIRIT_SELECT_LIMIT <= 15 +// +// [Pushed this down a little to make CW happy with BOOST_STATIC_ASSERT] +// [Otherwise, it complains: 'boost_static_assert_test_42' redefined] +// +/////////////////////////////////////////////////////////////////////////////// +BOOST_STATIC_ASSERT(BOOST_SPIRIT_SELECT_LIMIT <= PHOENIX_LIMIT); +BOOST_STATIC_ASSERT(BOOST_SPIRIT_SELECT_LIMIT > 0); +BOOST_STATIC_ASSERT(BOOST_SPIRIT_SELECT_LIMIT <= 15); + +/////////////////////////////////////////////////////////////////////////////// +// +// Calculate the required amount of tuple members rounded up to the nearest +// integer dividable by 3 +// +/////////////////////////////////////////////////////////////////////////////// +#if BOOST_SPIRIT_SELECT_LIMIT > 12 +#define BOOST_SPIRIT_SELECT_LIMIT_A 15 +#elif BOOST_SPIRIT_SELECT_LIMIT > 9 +#define BOOST_SPIRIT_SELECT_LIMIT_A 12 +#elif BOOST_SPIRIT_SELECT_LIMIT > 6 +#define BOOST_SPIRIT_SELECT_LIMIT_A 9 +#elif BOOST_SPIRIT_SELECT_LIMIT > 3 +#define BOOST_SPIRIT_SELECT_LIMIT_A 6 +#else +#define BOOST_SPIRIT_SELECT_LIMIT_A 3 +#endif + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// +// The select_default_no_fail and select_default_fail structs are used to +// distinguish two different behaviours for the select_parser in case that not +// any of the given sub-parsers match. +// +// If the select_parser is used with the select_default_no_fail behaviour, +// then in case of no matching sub-parser the whole select_parser returns an +// empty match and the value -1. +// +// If the select_parser is used with the select_default_fail behaviour, then +// in case of no matching sub-parser the whole select_parser fails to match at +// all. +// +/////////////////////////////////////////////////////////////////////////////// +struct select_default_no_fail {}; +struct select_default_fail {}; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/spirit/home/classic/dynamic/impl/select.ipp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +template <typename TupleT, typename BehaviourT, typename T> +struct select_parser +: public parser<select_parser<TupleT, BehaviourT, T> > +{ + typedef select_parser<TupleT, BehaviourT, T> self_t; + + select_parser(TupleT const &t_) + : t(t_) + {} + + template <typename ScannerT> + struct result + { + typedef typename match_result<ScannerT, T>::type type; + }; + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename parser_result<self_t, ScannerT>::type result_t; + + if (!scan.at_end()) { + return impl::parse_tuple_element< + TupleT::length, result_t, TupleT, BehaviourT>::do_(t, scan); + } + return impl::select_match_gen<result_t, BehaviourT>::do_(scan); + } + + TupleT const t; +}; + +/////////////////////////////////////////////////////////////////////////////// +template <typename BehaviourT, typename T = int> +struct select_parser_gen { + + /////////////////////////////////////////////////////////////////////////// + // + // This generates different select_parser_gen::operator()() functions with + // an increasing number of parser parameters: + // + // template <typename ParserT0, ...> + // select_parser< + // ::phoenix::tuple< + // typename impl::as_embedded_parser<ParserT0>::type, + // ... + // >, + // BehaviourT, + // T + // > + // operator()(ParserT0 const &p0, ...) const + // { + // typedef impl::as_embedded_parser<ParserT0> parser_t0; + // ... + // + // typedef ::phoenix::tuple< + // parser_t0::type, + // ... + // > tuple_t; + // typedef select_parser<tuple_t, BehaviourT, T> result_t; + // + // return result_t(tuple_t( + // parser_t0::convert(p0), + // ... + // )); + // } + // + // The number of generated functions depends on the maximum tuple member + // limit defined by the PHOENIX_LIMIT pp constant. + // + /////////////////////////////////////////////////////////////////////////// + #define BOOST_SPIRIT_SELECT_EMBEDDED(z, N, _) \ + typename impl::as_embedded_parser<BOOST_PP_CAT(ParserT, N)>::type \ + /**/ + #define BOOST_SPIRIT_SELECT_EMBEDDED_TYPEDEF(z, N, _) \ + typedef impl::as_embedded_parser<BOOST_PP_CAT(ParserT, N)> \ + BOOST_PP_CAT(parser_t, N); \ + /**/ + #define BOOST_SPIRIT_SELECT_CONVERT(z, N, _) \ + BOOST_PP_CAT(parser_t, N)::convert(BOOST_PP_CAT(p, N)) \ + /**/ + + #define BOOST_SPIRIT_SELECT_PARSER(z, N, _) \ + template < \ + BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), typename ParserT) \ + > \ + select_parser< \ + ::phoenix::tuple< \ + BOOST_PP_ENUM_ ## z(BOOST_PP_INC(N), \ + BOOST_SPIRIT_SELECT_EMBEDDED, _) \ + >, \ + BehaviourT, \ + T \ + > \ + operator()( \ + BOOST_PP_ENUM_BINARY_PARAMS_Z(z, BOOST_PP_INC(N), \ + ParserT, const &p) \ + ) const \ + { \ + BOOST_PP_REPEAT_ ## z(BOOST_PP_INC(N), \ + BOOST_SPIRIT_SELECT_EMBEDDED_TYPEDEF, _) \ + \ + typedef ::phoenix::tuple< \ + BOOST_PP_ENUM_BINARY_PARAMS_Z(z, BOOST_PP_INC(N), \ + typename parser_t, ::type BOOST_PP_INTERCEPT) \ + > tuple_t; \ + typedef select_parser<tuple_t, BehaviourT, T> result_t; \ + \ + return result_t(tuple_t( \ + BOOST_PP_ENUM_ ## z(BOOST_PP_INC(N), \ + BOOST_SPIRIT_SELECT_CONVERT, _) \ + )); \ + } \ + /**/ + + BOOST_PP_REPEAT(BOOST_SPIRIT_SELECT_LIMIT_A, + BOOST_SPIRIT_SELECT_PARSER, _) + + #undef BOOST_SPIRIT_SELECT_PARSER + #undef BOOST_SPIRIT_SELECT_CONVERT + #undef BOOST_SPIRIT_SELECT_EMBEDDED_TYPEDEF + #undef BOOST_SPIRIT_SELECT_EMBEDDED + /////////////////////////////////////////////////////////////////////////// +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// Predefined parser generator helper objects +// +/////////////////////////////////////////////////////////////////////////////// +select_parser_gen<select_default_no_fail> const select_p = + select_parser_gen<select_default_no_fail>(); + +select_parser_gen<select_default_fail> const select_fail_p = + select_parser_gen<select_default_fail>(); + +#undef BOOST_SPIRIT_SELECT_LIMIT_A + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif // BOOST_SPIRIT_SELECT_HPP diff --git a/boost/spirit/home/classic/dynamic/stored_rule.hpp b/boost/spirit/home/classic/dynamic/stored_rule.hpp new file mode 100644 index 0000000000..5661ef8855 --- /dev/null +++ b/boost/spirit/home/classic/dynamic/stored_rule.hpp @@ -0,0 +1,127 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_STORED_RULE_HPP) +#define BOOST_SPIRIT_STORED_RULE_HPP + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/non_terminal/impl/rule.ipp> +#include <boost/spirit/home/classic/dynamic/rule_alias.hpp> +#include <boost/shared_ptr.hpp> + +#include <boost/spirit/home/classic/dynamic/stored_rule_fwd.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // stored_rule class + // + /////////////////////////////////////////////////////////////////////////// + template < + typename T0 + , typename T1 + , typename T2 + , bool EmbedByValue + > + class stored_rule + : public impl::rule_base< + stored_rule<T0, T1, T2, EmbedByValue> + , typename mpl::if_c< + EmbedByValue + , stored_rule<T0, T1, T2, true> + , stored_rule<T0, T1, T2> const&>::type + , T0, T1, T2> + { + public: + + typedef stored_rule<T0, T1, T2, EmbedByValue> self_t; + typedef impl::rule_base< + self_t + , typename mpl::if_c< + EmbedByValue + , stored_rule<T0, T1, T2, true> + , self_t const&>::type + , T0, T1, T2> + base_t; + + typedef typename base_t::scanner_t scanner_t; + typedef typename base_t::attr_t attr_t; + typedef impl::abstract_parser<scanner_t, attr_t> abstract_parser_t; + typedef rule_alias<self_t> alias_t; + + stored_rule() : ptr() {} + ~stored_rule() {} + + stored_rule(stored_rule const& r) + : ptr(r.ptr) {} + + template <typename ParserT> + stored_rule(ParserT const& p) + : ptr(new impl::concrete_parser<ParserT, scanner_t, attr_t>(p)) {} + + template <typename ParserT> + stored_rule& operator=(ParserT const& p) + { + ptr.reset(new impl::concrete_parser<ParserT, scanner_t, attr_t>(p)); + return *this; + } + + stored_rule& operator=(stored_rule const& r) + { + // If this is placed above the templatized assignment + // operator, VC6 incorrectly complains ambiguity with + // r1 = r2, where r1 and r2 are both rules. + ptr = r.ptr; + return *this; + } + + stored_rule<T0, T1, T2, true> + copy() const + { + return stored_rule<T0, T1, T2, true>(ptr); + } + + alias_t + alias() const + { + return alias_t(*this); + } + + private: + + friend class impl::rule_base_access; + friend class stored_rule<T0, T1, T2, !EmbedByValue>; + +#if defined(__GNUC__) && (__GNUC__ < 3) + public: +#endif + abstract_parser_t* + get() const + { + return ptr.get(); + } +#if defined(__GNUC__) && (__GNUC__ < 3) + private: +#endif + + stored_rule(shared_ptr<abstract_parser_t> const& ptr) + : ptr(ptr) {} + + shared_ptr<abstract_parser_t> ptr; + }; + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif diff --git a/boost/spirit/home/classic/dynamic/stored_rule_fwd.hpp b/boost/spirit/home/classic/dynamic/stored_rule_fwd.hpp new file mode 100644 index 0000000000..655bd838a9 --- /dev/null +++ b/boost/spirit/home/classic/dynamic/stored_rule_fwd.hpp @@ -0,0 +1,31 @@ +/*============================================================================= + Copyright (c) 2006 Tobias Schwinger + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_STORED_RULE_FWD_HPP) +#define BOOST_SPIRIT_STORED_RULE_FWD_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/nil.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + template < + typename T0 = nil_t + , typename T1 = nil_t + , typename T2 = nil_t + , bool EmbedByValue = false + > + class stored_rule; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + diff --git a/boost/spirit/home/classic/dynamic/switch.hpp b/boost/spirit/home/classic/dynamic/switch.hpp new file mode 100644 index 0000000000..4a2c7e463e --- /dev/null +++ b/boost/spirit/home/classic/dynamic/switch.hpp @@ -0,0 +1,259 @@ +/*============================================================================= + Copyright (c) 2003 Hartmut Kaiser + 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_SWITCH_HPP +#define BOOST_SPIRIT_SWITCH_HPP + +/////////////////////////////////////////////////////////////////////////////// +// +// The default_p parser generator template uses the following magic number +// as the corresponding case label value inside the generated switch() +// statements. If this number conflicts with your code, please pick a +// different one. +// +/////////////////////////////////////////////////////////////////////////////// +#if !defined(BOOST_SPIRIT_DEFAULTCASE_MAGIC) +#define BOOST_SPIRIT_DEFAULTCASE_MAGIC 0x15F97A7 +#endif + +/////////////////////////////////////////////////////////////////////////////// +// +// Spirit predefined maximum number of possible case_p/default_p case branch +// parsers. +// +/////////////////////////////////////////////////////////////////////////////// +#if !defined(BOOST_SPIRIT_SWITCH_CASE_LIMIT) +#define BOOST_SPIRIT_SWITCH_CASE_LIMIT 3 +#endif // !defined(BOOST_SPIRIT_SWITCH_CASE_LIMIT) + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/static_assert.hpp> + +/////////////////////////////////////////////////////////////////////////////// +// +// Ensure BOOST_SPIRIT_SELECT_LIMIT > 0 +// +/////////////////////////////////////////////////////////////////////////////// +BOOST_STATIC_ASSERT(BOOST_SPIRIT_SWITCH_CASE_LIMIT > 0); + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/config.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/core/composite/epsilon.hpp> +#include <boost/spirit/home/classic/dynamic/impl/switch.ipp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// +// The switch_parser allows to build switch like parsing constructs, which +// will have much better perfomance as comparable straight solutions. +// +// Input stream driven syntax: +// +// switch_p +// [ +// case_p<'a'> +// (...parser to use, if the next character is 'a'...), +// case_p<'b'> +// (...parser to use, if the next character is 'b'...), +// default_p +// (...parser to use, if nothing was matched before...) +// ] +// +// General syntax: +// +// switch_p(...lazy expression returning the switch condition value...) +// [ +// case_p<1> +// (...parser to use, if the switch condition value is 1...), +// case_p<2> +// (...parser to use, if the switch condition value is 2...), +// default_p +// (...parser to use, if nothing was matched before...) +// ] +// +// The maximum number of possible case_p branches is defined by the p constant +// BOOST_SPIRIT_SWITCH_CASE_LIMIT (this value defaults to 3 if not otherwise +// defined). +// +/////////////////////////////////////////////////////////////////////////////// +template <typename CaseT, typename CondT = impl::get_next_token_cond> +struct switch_parser +: public unary<CaseT, parser<switch_parser<CaseT, CondT> > > +{ + typedef switch_parser<CaseT, CondT> self_t; + typedef unary_parser_category parser_category_t; + typedef unary<CaseT, parser<self_t> > base_t; + + switch_parser(CaseT const &case_) + : base_t(case_), cond(CondT()) + {} + + switch_parser(CaseT const &case_, CondT const &cond_) + : base_t(case_), cond(cond_) + {} + + template <typename ScannerT> + struct result + { + typedef typename match_result<ScannerT, nil_t>::type type; + }; + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + return this->subject().parse(scan, + impl::make_cond_functor<CondT>::do_(cond)); + } + + CondT cond; +}; + +/////////////////////////////////////////////////////////////////////////////// +template <typename CondT> +struct switch_cond_parser +{ + switch_cond_parser(CondT const &cond_) + : cond(cond_) + {} + + template <typename ParserT> + switch_parser<ParserT, CondT> + operator[](parser<ParserT> const &p) const + { + return switch_parser<ParserT, CondT>(p.derived(), cond); + } + + CondT const &cond; +}; + +/////////////////////////////////////////////////////////////////////////////// +template <int N, typename ParserT, bool IsDefault> +struct case_parser +: public unary<ParserT, parser<case_parser<N, ParserT, IsDefault> > > +{ + typedef case_parser<N, ParserT, IsDefault> self_t; + typedef unary_parser_category parser_category_t; + typedef unary<ParserT, parser<self_t> > base_t; + + typedef typename base_t::subject_t self_subject_t; + + BOOST_STATIC_CONSTANT(int, value = N); + BOOST_STATIC_CONSTANT(bool, is_default = IsDefault); + BOOST_STATIC_CONSTANT(bool, is_simple = true); + BOOST_STATIC_CONSTANT(bool, is_epsilon = ( + is_default && boost::is_same<self_subject_t, epsilon_parser>::value + )); + + case_parser(parser<ParserT> const &p) + : base_t(p.derived()) + {} + + template <typename ScannerT> + struct result + { + typedef typename match_result<ScannerT, nil_t>::type type; + }; + + template <typename ScannerT, typename CondT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan, CondT const &cond) const + { + typedef impl::default_case<self_t> default_t; + + if (!scan.at_end()) { + typedef impl::default_delegate_parse< + value, is_default, default_t::value> default_parse_t; + + typename ScannerT::iterator_t const save(scan.first); + return default_parse_t::parse(cond(scan), *this, + *this, scan, save); + } + + return default_t::is_epsilon ? scan.empty_match() : scan.no_match(); + } + + template <int N1, typename ParserT1, bool IsDefault1> + impl::compound_case_parser< + self_t, case_parser<N1, ParserT1, IsDefault1>, IsDefault1 + > + operator, (case_parser<N1, ParserT1, IsDefault1> const &p) const + { + // If the following compile time assertion fires, you've probably used + // more than one default_p case inside the switch_p parser construct. + BOOST_STATIC_ASSERT(!is_default || !IsDefault1); + + typedef case_parser<N1, ParserT1, IsDefault1> right_t; + return impl::compound_case_parser<self_t, right_t, IsDefault1>(*this, p); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +struct switch_parser_gen { + +// This generates a switch parser, which is driven by the condition value +// returned by the lazy parameter expression 'cond'. This may be a parser, +// which result is used or a phoenix actor, which will be dereferenced to +// obtain the switch condition value. + template <typename CondT> + switch_cond_parser<CondT> + operator()(CondT const &cond) const + { + return switch_cond_parser<CondT>(cond); + } + +// This generates a switch parser, which is driven by the next character/token +// found in the input stream. + template <typename CaseT> + switch_parser<CaseT> + operator[](parser<CaseT> const &p) const + { + return switch_parser<CaseT>(p.derived()); + } +}; + +switch_parser_gen const switch_p = switch_parser_gen(); + +/////////////////////////////////////////////////////////////////////////////// +template <int N, typename ParserT> +inline case_parser<N, ParserT, false> +case_p(parser<ParserT> const &p) +{ + return case_parser<N, ParserT, false>(p); +} + +/////////////////////////////////////////////////////////////////////////////// +struct default_parser_gen +: public case_parser<BOOST_SPIRIT_DEFAULTCASE_MAGIC, epsilon_parser, true> +{ + default_parser_gen() + : case_parser<BOOST_SPIRIT_DEFAULTCASE_MAGIC, epsilon_parser, true> + (epsilon_p) + {} + + template <typename ParserT> + case_parser<BOOST_SPIRIT_DEFAULTCASE_MAGIC, ParserT, true> + operator()(parser<ParserT> const &p) const + { + return case_parser<BOOST_SPIRIT_DEFAULTCASE_MAGIC, ParserT, true>(p); + } +}; + +default_parser_gen const default_p = default_parser_gen(); + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif // BOOST_SPIRIT_SWITCH_HPP diff --git a/boost/spirit/home/classic/dynamic/typeof.hpp b/boost/spirit/home/classic/dynamic/typeof.hpp new file mode 100644 index 0000000000..7ed99c657b --- /dev/null +++ b/boost/spirit/home/classic/dynamic/typeof.hpp @@ -0,0 +1,89 @@ +/*============================================================================= + Copyright (c) 2006 Tobias Schwinger + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_DYNAMIC_TYPEOF_HPP) +#define BOOST_SPIRIT_DYNAMIC_TYPEOF_HPP + +#include <boost/typeof/typeof.hpp> + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/typeof.hpp> + +#include <boost/spirit/home/classic/dynamic/stored_rule_fwd.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + // if.hpp + template <class ParsableT, typename CondT> struct if_parser; + template <class ParsableTrueT, class ParsableFalseT, typename CondT> + struct if_else_parser; + + // for.hpp + namespace impl { + template<typename InitF, typename CondT, typename StepF, class ParsableT> + struct for_parser; + } + + // while.hpp + template<typename ParsableT, typename CondT, bool is_do_parser> + struct while_parser; + + // lazy.hpp + template<typename ActorT> struct lazy_parser; + + // rule_alias.hpp + template <typename ParserT> class rule_alias; + + // switch.hpp + template <typename CaseT, typename CondT> struct switch_parser; + template <int N, class ParserT, bool IsDefault> struct case_parser; + + // select.hpp + template <typename TupleT, typename BehaviourT, typename T> + struct select_parser; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + + +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() + +// if.hpp +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::if_parser,2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::if_else_parser,3) + +// for.hpp +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::impl::for_parser,4) + +// while.hpp +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::while_parser,(class)(class)(bool)) + +// lazy.hpp +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::lazy_parser,1) + +// stored_rule.hpp (has forward header) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::stored_rule,(typename)(typename)(typename)(bool)) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::stored_rule,3) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::stored_rule,2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::stored_rule,1) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::stored_rule<>) + +// rule_alias.hpp +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::rule_alias,1) + +// switch.hpp +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::switch_parser,2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::case_parser,(int)(class)(bool)) + +// select.hpp +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::select_parser,3) + +#endif + diff --git a/boost/spirit/home/classic/dynamic/while.hpp b/boost/spirit/home/classic/dynamic/while.hpp new file mode 100644 index 0000000000..e441e9c486 --- /dev/null +++ b/boost/spirit/home/classic/dynamic/while.hpp @@ -0,0 +1,189 @@ +/*============================================================================= + Copyright (c) 2002-2003 Joel de Guzman + Copyright (c) 2002-2003 Martin Wille + 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_WHILE_HPP +#define BOOST_SPIRIT_WHILE_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/core/composite/composite.hpp> +#include <boost/spirit/home/classic/dynamic/impl/conditions.ipp> + +//////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + namespace impl { + + ////////////////////////////////// + // while parser + // object are created by while_parser_gen and do_parser_gen + template <typename ParsableT, typename CondT, bool is_do_parser> + struct while_parser + : public condition_evaluator< typename as_parser<CondT>::type > + , public unary // the parent stores a copy of the body parser + < + typename as_parser<ParsableT>::type, + parser<while_parser<ParsableT, CondT, is_do_parser> > + > + { + typedef while_parser<ParsableT, CondT, is_do_parser> self_t; + + typedef as_parser<ParsableT> as_parser_t; + typedef typename as_parser_t::type parser_t; + typedef as_parser<CondT> cond_as_parser_t; + typedef typename cond_as_parser_t::type condition_t; + + typedef unary<parser_t, parser<self_t> > base_t; + typedef condition_evaluator<condition_t> eval_t; + + + ////////////////////////////// + // constructor, saves condition and body parser + while_parser(ParsableT const &body, CondT const &cond) + : eval_t(cond_as_parser_t::convert(cond)) + , base_t(as_parser_t::convert(body)) + {} + + ////////////////////////////// + // result type computer. + template <typename ScannerT> + struct result + { + typedef typename match_result + <ScannerT, nil_t>::type type; + }; + + ////////////////////////////// + // parse member function + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename parser_result<parser_t, ScannerT>::type sresult_t; + typedef typename ScannerT::iterator_t iterator_t; + + iterator_t save(scan.first); + std::size_t length = 0; + int eval_length = 0; + + bool dont_check_condition = is_do_parser; + + while (dont_check_condition || (eval_length=this->evaluate(scan))>=0) + { + dont_check_condition = false; + length += eval_length; + sresult_t tmp(this->subject().parse(scan)); + if (tmp) + { + length+=tmp.length(); + } + else + { + return scan.no_match(); + } + } + return scan.create_match(length, nil_t(), save, scan.first); + } + }; + + ////////////////////////////////// + // while-parser generator, takes the body-parser in brackets + // and returns the actual while-parser. + template <typename CondT> + struct while_parser_gen + { + ////////////////////////////// + // constructor, saves the condition for use by operator[] + while_parser_gen(CondT const& cond_) : cond(cond_) {} + + ////////////////////////////// + // operator[] returns the actual while-parser object + template <typename ParsableT> + while_parser<ParsableT, CondT, false> + operator[](ParsableT const &subject) const + { + return while_parser<ParsableT, CondT, false>(subject, cond); + } + private: + + ////////////////////////////// + // the condition is stored by reference here. + // this should not cause any harm since object of type + // while_parser_gen<> are only used as temporaries + // the while-parser object constructed by the operator[] + // stores a copy of the condition. + CondT const &cond; + }; + + ////////////////////////////////// + // do-while-parser generator, takes the condition as + // parameter to while_p member function and returns the + // actual do-while-parser. + template <typename ParsableT> + struct do_while_parser_gen + { + ////////////////////////////// + // constructor. saves the body parser for use by while_p. + explicit do_while_parser_gen(ParsableT const &body_parser) + : body(body_parser) + {} + + ////////////////////////////// + // while_p returns the actual while-parser object + template <typename CondT> + while_parser<ParsableT, CondT, true> + while_p(CondT cond) const + { + return while_parser<ParsableT, CondT, true>(body, cond); + } + private: + + ////////////////////////////// + // the body is stored by reference here + // this should not cause any harm since object of type + // do_while_parser_gen<> are only used as temporaries + // the while-parser object constructed by the while_p + // member function stores a copy of the body parser. + ParsableT const &body; + }; + + struct do_parser_gen + { + inline do_parser_gen() {} + + template <typename ParsableT> + impl::do_while_parser_gen<ParsableT> + operator[](ParsableT const& body) const + { + return impl::do_while_parser_gen<ParsableT>(body); + } + }; +} // namespace impl + +////////////////////////////////// +// while_p function, while-parser generator +// Usage: spirit::while_p(Condition)[Body] +template <typename CondT> +impl::while_parser_gen<CondT> +while_p(CondT const& cond) +{ + return impl::while_parser_gen<CondT>(cond); +} + +////////////////////////////////// +// do_p functor, do-while-parser generator +// Usage: spirit::do_p[Body].while_p(Condition) +impl::do_parser_gen const do_p = impl::do_parser_gen(); + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif // BOOST_SPIRIT_WHILE_HPP diff --git a/boost/spirit/home/classic/error_handling.hpp b/boost/spirit/home/classic/error_handling.hpp new file mode 100644 index 0000000000..72c5d2cac2 --- /dev/null +++ b/boost/spirit/home/classic/error_handling.hpp @@ -0,0 +1,21 @@ +/*============================================================================= + Copyright (c) 2001-2003 Joel de Guzman + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_ERROR_HANDLING_MAIN_HPP) +#define BOOST_SPIRIT_ERROR_HANDLING_MAIN_HPP + +#include <boost/spirit/home/classic/version.hpp> + +/////////////////////////////////////////////////////////////////////////////// +// +// Master header for Spirit.ErrorHandling +// +/////////////////////////////////////////////////////////////////////////////// + +#include <boost/spirit/home/classic/error_handling/exceptions.hpp> + +#endif // !defined(BOOST_SPIRIT_ERROR_HANDLING_MAIN_HPP) diff --git a/boost/spirit/home/classic/error_handling/exceptions.hpp b/boost/spirit/home/classic/error_handling/exceptions.hpp new file mode 100644 index 0000000000..c2e0c86983 --- /dev/null +++ b/boost/spirit/home/classic/error_handling/exceptions.hpp @@ -0,0 +1,365 @@ +/*============================================================================= + Copyright (c) 2001-2003 Joel de Guzman + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#ifndef BOOST_SPIRIT_EXCEPTIONS_HPP +#define BOOST_SPIRIT_EXCEPTIONS_HPP + +#include <boost/config.hpp> +#include <boost/throw_exception.hpp> +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/core/composite/composite.hpp> +#include <exception> + +#include <boost/spirit/home/classic/error_handling/exceptions_fwd.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // parser_error_base class + // + // This is the base class of parser_error (see below). This may be + // used to catch any type of parser error. + // + // This exception shouldn't propagate outside the parser. However to + // avoid quirks of many platforms/implementations which fall outside + // the C++ standard, we derive parser_error_base from std::exception + // to allow a single catch handler to catch all exceptions. + // + /////////////////////////////////////////////////////////////////////////// + class parser_error_base : public std::exception + { + protected: + + parser_error_base() {} + virtual ~parser_error_base() throw() {} + + public: + + parser_error_base(parser_error_base const& rhs) + : std::exception(rhs) {} + parser_error_base& operator=(parser_error_base const&) + { + return *this; + } + }; + + /////////////////////////////////////////////////////////////////////////// + // + // parser_error class + // + // Generic parser exception class. This is the base class for all + // parser exceptions. The exception holds the iterator position + // where the error was encountered in its member variable "where". + // The parser_error also holds information regarding the error + // (error descriptor) in its member variable "descriptor". + // + // The throw_ function creates and throws a parser_error given + // an iterator and an error descriptor. + // + /////////////////////////////////////////////////////////////////////////// + template <typename ErrorDescrT, typename IteratorT> + struct parser_error : public parser_error_base + { + typedef ErrorDescrT error_descr_t; + typedef IteratorT iterator_t; + + parser_error(IteratorT where_, ErrorDescrT descriptor_) + : where(where_), descriptor(descriptor_) {} + + parser_error(parser_error const& rhs) + : parser_error_base(rhs) + , where(rhs.where), descriptor(rhs.descriptor) {} + + parser_error& + operator=(parser_error const& rhs) + { + where = rhs.where; + descriptor = rhs.descriptor; + return *this; + } + + virtual + ~parser_error() throw() {} + + virtual const char* + what() const throw() + { + return "BOOST_SPIRIT_CLASSIC_NS::parser_error"; + } + + IteratorT where; + ErrorDescrT descriptor; + }; + + ////////////////////////////////// + template <typename ErrorDescrT, typename IteratorT> + inline void + throw_(IteratorT where, ErrorDescrT descriptor) + { + boost::throw_exception( + parser_error<ErrorDescrT, IteratorT>(where, descriptor)); + } + + /////////////////////////////////////////////////////////////////////////// + // + // assertive_parser class + // + // An assertive_parser class is a parser that throws an exception + // in response to a parsing failure. The assertive_parser throws a + // parser_error exception rather than returning an unsuccessful + // match to signal that the parser failed to match the input. + // + /////////////////////////////////////////////////////////////////////////// + template <typename ErrorDescrT, typename ParserT> + struct assertive_parser + : public unary<ParserT, parser<assertive_parser<ErrorDescrT, ParserT> > > + { + typedef assertive_parser<ErrorDescrT, ParserT> self_t; + typedef unary<ParserT, parser<self_t> > base_t; + typedef unary_parser_category parser_category_t; + + assertive_parser(ParserT const& parser, ErrorDescrT descriptor_) + : base_t(parser), descriptor(descriptor_) {} + + template <typename ScannerT> + struct result + { + typedef typename parser_result<ParserT, ScannerT>::type type; + }; + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename parser_result<ParserT, ScannerT>::type result_t; + typedef typename ScannerT::iterator_t iterator_t; + + result_t hit = this->subject().parse(scan); + if (!hit) + { + throw_(scan.first, descriptor); + } + return hit; + } + + ErrorDescrT descriptor; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // assertion class + // + // assertive_parsers are never instantiated directly. The assertion + // class is used to indirectly create an assertive_parser object. + // Before declaring the grammar, we declare some assertion objects. + // Examples: + // + // enum Errors + // { + // program_expected, begin_expected, end_expected + // }; + // + // assertion<Errors> expect_program(program_expected); + // assertion<Errors> expect_begin(begin_expected); + // assertion<Errors> expect_end(end_expected); + // + // Now, we can use these assertions as wrappers around parsers: + // + // expect_end(str_p("end")) + // + // Take note that although the example uses enums to hold the + // information regarding the error (error desccriptor), we are free + // to use other types such as integers and strings. Enums are + // convenient for error handlers to easily catch since C++ treats + // enums as unique types. + // + /////////////////////////////////////////////////////////////////////////// + template <typename ErrorDescrT> + struct assertion + { + assertion(ErrorDescrT descriptor_) + : descriptor(descriptor_) {} + + template <typename ParserT> + assertive_parser<ErrorDescrT, ParserT> + operator()(ParserT const& parser) const + { + return assertive_parser<ErrorDescrT, ParserT>(parser, descriptor); + } + + ErrorDescrT descriptor; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // error_status<T> + // + // Where T is an attribute type compatible with the match attribute + // of the fallback_parser's subject (defaults to nil_t). The class + // error_status reports the result of an error handler (see + // fallback_parser). result can be one of: + // + // fail: quit and fail (return a no_match) + // retry: attempt error recovery, possibly moving the scanner + // accept: force success returning a matching length, moving + // the scanner appropriately and returning an attribute + // value + // rethrow: rethrows the error. + // + /////////////////////////////////////////////////////////////////////////// + template <typename T> + struct error_status + { + enum result_t { fail, retry, accept, rethrow }; + + error_status( + result_t result_ = fail, + std::ptrdiff_t length_ = -1, + T const& value_ = T()) + : result(result_), length(length_), value(value_) {} + + result_t result; + std::ptrdiff_t length; + T value; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // fallback_parser class + // + // Handles exceptions of type parser_error<ErrorDescrT, IteratorT> + // thrown somewhere inside its embedded ParserT object. The class + // sets up a try block before delegating parsing to its subject. + // When an exception is caught, the catch block then calls the + // HandlerT object. HandlerT may be a function or a functor (with + // an operator() member function) compatible with the interface: + // + // error_status<T> + // handler(ScannerT const& scan, ErrorT error); + // + // Where scan points to the scanner state prior to parsing and error + // is the error that arose (see parser_error). The handler must + // return an error_status<T> object (see above). + // + /////////////////////////////////////////////////////////////////////////// + namespace impl + { + template <typename RT, typename ParserT, typename ScannerT> + RT fallback_parser_parse(ParserT const& p, ScannerT const& scan); + } + + template <typename ErrorDescrT, typename ParserT, typename HandlerT> + struct fallback_parser + : public unary<ParserT, + parser<fallback_parser<ErrorDescrT, ParserT, HandlerT> > > + { + typedef fallback_parser<ErrorDescrT, ParserT, HandlerT> + self_t; + typedef ErrorDescrT + error_descr_t; + typedef unary<ParserT, parser<self_t> > + base_t; + typedef unary_parser_category + parser_category_t; + + fallback_parser(ParserT const& parser, HandlerT const& handler_) + : base_t(parser), handler(handler_) {} + + template <typename ScannerT> + struct result + { + typedef typename parser_result<ParserT, ScannerT>::type type; + }; + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename parser_result<self_t, ScannerT>::type result_t; + return impl::fallback_parser_parse<result_t>(*this, scan); + } + + HandlerT handler; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // guard class + // + // fallback_parser objects are not instantiated directly. The guard + // class is used to indirectly create a fallback_parser object. + // guards are typically predeclared just like assertions (see the + // assertion class above; the example extends the previous example + // introduced in the assertion class above): + // + // guard<Errors> my_guard; + // + // Errors, in this example is the error descriptor type we want to + // detect; This is essentially the ErrorDescrT template parameter + // of the fallback_parser class. + // + // my_guard may now be used in a grammar declaration as: + // + // my_guard(p)[h] + // + // where p is a parser, h is a function or functor compatible with + // fallback_parser's HandlerT (see above). + // + /////////////////////////////////////////////////////////////////////////// + template <typename ErrorDescrT, typename ParserT> + struct guard_gen : public unary<ParserT, nil_t> + { + typedef guard<ErrorDescrT> parser_generator_t; + typedef unary_parser_category parser_category_t; + + guard_gen(ParserT const& p) + : unary<ParserT, nil_t>(p) {} + + template <typename HandlerT> + fallback_parser<ErrorDescrT, ParserT, HandlerT> + operator[](HandlerT const& handler) const + { + return fallback_parser<ErrorDescrT, ParserT, HandlerT> + (this->subject(), handler); + } + }; + + template <typename ErrorDescrT> + struct guard + { + template <typename ParserT> + struct result + { + typedef guard_gen<ErrorDescrT, ParserT> type; + }; + + template <typename ParserT> + static guard_gen<ErrorDescrT, ParserT> + generate(ParserT const& parser) + { + return guard_gen<ErrorDescrT, ParserT>(parser); + } + + template <typename ParserT> + guard_gen<ErrorDescrT, ParserT> + operator()(ParserT const& parser) const + { + return guard_gen<ErrorDescrT, ParserT>(parser); + } + }; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#include <boost/spirit/home/classic/error_handling/impl/exceptions.ipp> +#endif + diff --git a/boost/spirit/home/classic/error_handling/exceptions_fwd.hpp b/boost/spirit/home/classic/error_handling/exceptions_fwd.hpp new file mode 100644 index 0000000000..a8c132cf81 --- /dev/null +++ b/boost/spirit/home/classic/error_handling/exceptions_fwd.hpp @@ -0,0 +1,41 @@ +/*============================================================================= + Copyright (c) 2006 Tobias Schwinger + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_EXCEPTIONS_FWD_HPP) +#define BOOST_SPIRIT_EXCEPTIONS_FWD_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/nil.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + template <typename ErrorDescrT, typename IteratorT = char const*> + struct parser_error; + + template <typename ErrorDescrT, typename ParserT> + struct assertive_parser; + + template <typename ErrorDescrT> + struct assertion; + + template <typename T = nil_t> + struct error_status; + + template <typename ErrorDescrT, typename ParserT, typename HandlerT> + struct fallback_parser; + + template <typename ErrorDescrT> + struct guard; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + diff --git a/boost/spirit/home/classic/error_handling/impl/exceptions.ipp b/boost/spirit/home/classic/error_handling/impl/exceptions.ipp new file mode 100644 index 0000000000..1cc63e798c --- /dev/null +++ b/boost/spirit/home/classic/error_handling/impl/exceptions.ipp @@ -0,0 +1,93 @@ +/*============================================================================= + 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_SPIRIT_EXCEPTIONS_IPP +#define BOOST_SPIRIT_EXCEPTIONS_IPP + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +namespace impl { + +#ifdef __BORLANDC__ + template <typename ParserT, typename ScannerT> + typename parser_result<ParserT, ScannerT>::type + fallback_parser_helper(ParserT const& subject, ScannerT const& scan); +#endif + + template <typename RT, typename ParserT, typename ScannerT> + RT fallback_parser_parse(ParserT const& p, ScannerT const& scan) + { + typedef typename ScannerT::iterator_t iterator_t; + typedef typename RT::attr_t attr_t; + typedef error_status<attr_t> error_status_t; + typedef typename ParserT::error_descr_t error_descr_t; + + iterator_t save = scan.first; + error_status_t hr(error_status_t::retry); + + while (hr.result == error_status_t::retry) + { + try + { + #ifndef __BORLANDC__ + return p.subject().parse(scan); + #else + return impl::fallback_parser_helper(p, scan); + #endif + } + + catch (parser_error<error_descr_t, iterator_t>& error) + { + scan.first = save; + hr = p.handler(scan, error); + switch (hr.result) + { + case error_status_t::fail: + return scan.no_match(); + case error_status_t::accept: + return scan.create_match + (std::size_t(hr.length), hr.value, save, scan.first); + case error_status_t::rethrow: + boost::throw_exception(error); + default: + continue; + } + } + } + return scan.no_match(); + } + +/////////////////////////////////////////////////////////////////////////// +// +// Borland does not like calling the subject directly in the try block. +// Removing the #ifdef __BORLANDC__ code makes Borland complain that +// some variables and types cannot be found in the catch block. Weird! +// +/////////////////////////////////////////////////////////////////////////// +#ifdef __BORLANDC__ + + template <typename ParserT, typename ScannerT> + typename parser_result<ParserT, ScannerT>::type + fallback_parser_helper(ParserT const& p, ScannerT const& scan) + { + return p.subject().parse(scan); + } + +#endif + +} + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit::impl + +/////////////////////////////////////////////////////////////////////////////// +#endif + diff --git a/boost/spirit/home/classic/error_handling/typeof.hpp b/boost/spirit/home/classic/error_handling/typeof.hpp new file mode 100644 index 0000000000..9e31cce62b --- /dev/null +++ b/boost/spirit/home/classic/error_handling/typeof.hpp @@ -0,0 +1,33 @@ +/*============================================================================= + Copyright (c) 2006 Tobias Schwinger + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_ERROR_HANDLING_TYPEOF_HPP) +#define BOOST_SPIRIT_ERROR_HANDLING_TYPEOF_HPP + +#include <boost/typeof/typeof.hpp> + +#include <boost/spirit/home/classic/core/typeof.hpp> + +#include <boost/spirit/home/classic/error_handling/exceptions_fwd.hpp> + + +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() + + +// exceptions.hpp (has forward header) + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::parser_error,2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::assertive_parser,2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::error_status,1) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::fallback_parser,3) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::guard,1) + +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::error_status<>) + + +#endif + diff --git a/boost/spirit/home/classic/iterator.hpp b/boost/spirit/home/classic/iterator.hpp new file mode 100644 index 0000000000..fb2b68f17c --- /dev/null +++ b/boost/spirit/home/classic/iterator.hpp @@ -0,0 +1,25 @@ +/*============================================================================= + Copyright (c) 2001-2003 Daniel Nuffer + Copyright (c) 2003 Giovanni Bajo + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_ITERATOR_MAIN_HPP) +#define BOOST_SPIRIT_ITERATOR_MAIN_HPP + +#include <boost/spirit/home/classic/version.hpp> + +/////////////////////////////////////////////////////////////////////////////// +// +// Master header for Spirit.Iterators +// +/////////////////////////////////////////////////////////////////////////////// + +#include <boost/spirit/home/classic/iterator/file_iterator.hpp> +#include <boost/spirit/home/classic/iterator/fixed_size_queue.hpp> +#include <boost/spirit/home/classic/iterator/position_iterator.hpp> +#include <boost/spirit/home/classic/iterator/multi_pass.hpp> + +#endif // !defined(BOOST_SPIRIT_ITERATOR_MAIN_HPP) diff --git a/boost/spirit/home/classic/iterator/file_iterator.hpp b/boost/spirit/home/classic/iterator/file_iterator.hpp new file mode 100644 index 0000000000..5c20f15fe3 --- /dev/null +++ b/boost/spirit/home/classic/iterator/file_iterator.hpp @@ -0,0 +1,229 @@ +/*============================================================================= + Copyright (c) 2003 Giovanni Bajo + Copyright (c) 2003 Thomas Witt + Copyright (c) 2003 Hartmut Kaiser + 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) +=============================================================================*/ + +/////////////////////////////////////////////////////////////////////////////// +// +// File Iterator structure +// +// The new structure is designed on layers. The top class (used by the user) +// is file_iterator, which implements a full random access iterator through +// the file, and some specific member functions (constructor that opens +// the file, make_end() to generate the end iterator, operator bool to check +// if the file was opened correctly). +// +// file_iterator implements the random access iterator interface by the means +// of boost::iterator_adaptor, that is inhering an object created with it. +// iterator_adaptor gets a low-level file iterator implementation (with just +// a few member functions) and a policy (that basically describes to it how +// the low-level file iterator interface is). The advantage is that +// with boost::iterator_adaptor only 5 functions are needed to implement +// a fully conformant random access iterator, instead of dozens of functions +// and operators. +// +// There are two low-level file iterators implemented in this module. The +// first (std_file_iterator) uses cstdio stream functions (fopen/fread), which +// support full buffering, and is available everywhere (it's standard C++). +// The second (mmap_file_iterator) is currently available only on Windows +// platforms, and uses memory mapped files, which gives a decent speed boost. +// +/////////////////////////////////////////////////////////////////////////////// +// +// TODO LIST: +// +// - In the Win32 mmap iterator, we could check if keeping a handle to the +// opened file is really required. If it's not, we can just store the file +// length (for make_end()) and save performance. Notice that this should be +// tested under different Windows versions, the behaviour might change. +// - Add some error support (by the means of some exceptions) in case of +// low-level I/O failure. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_SPIRIT_FILE_ITERATOR_HPP +#define BOOST_SPIRIT_FILE_ITERATOR_HPP + +#include <string> +#include <boost/config.hpp> +#include <boost/iterator_adaptors.hpp> +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/safe_bool.hpp> + +#include <boost/spirit/home/classic/iterator/file_iterator_fwd.hpp> + +#if !defined(BOOST_SPIRIT_FILEITERATOR_STD) +# if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) \ + && !defined(BOOST_DISABLE_WIN32) +# define BOOST_SPIRIT_FILEITERATOR_WINDOWS +# elif defined(BOOST_HAS_UNISTD_H) +extern "C" +{ +# include <unistd.h> +} +# ifdef _POSIX_MAPPED_FILES +# define BOOST_SPIRIT_FILEITERATOR_POSIX +# endif // _POSIX_MAPPED_FILES +# endif // BOOST_HAS_UNISTD_H + +# if !defined(BOOST_SPIRIT_FILEITERATOR_WINDOWS) && \ + !defined(BOOST_SPIRIT_FILEITERATOR_POSIX) +# define BOOST_SPIRIT_FILEITERATOR_STD +# endif +#endif // BOOST_SPIRIT_FILEITERATOR_STD + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +template < + typename CharT = char, + typename BaseIterator = +#ifdef BOOST_SPIRIT_FILEITERATOR_STD + fileiter_impl::std_file_iterator<CharT> +#else + fileiter_impl::mmap_file_iterator<CharT> +#endif +> class file_iterator; + +/////////////////////////////////////////////////////////////////////////////// +namespace fileiter_impl { + + ///////////////////////////////////////////////////////////////////////// + // + // file_iter_generator + // + // Template meta-function to invoke boost::iterator_adaptor + // NOTE: This cannot be moved into the implementation file because of + // a bug of MSVC 7.0 and previous versions (base classes types are + // looked up at compilation time, not instantion types, and + // file_iterator would break). + // + ///////////////////////////////////////////////////////////////////////// + +#if !defined(BOOST_ITERATOR_ADAPTORS_VERSION) || \ + BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200 +#error "Please use at least Boost V1.31.0 while compiling the file_iterator class!" +#else // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200 + + template <typename CharT, typename BaseIteratorT> + struct file_iter_generator + { + public: + typedef BaseIteratorT adapted_t; + typedef typename adapted_t::value_type value_type; + + typedef boost::iterator_adaptor < + file_iterator<CharT, BaseIteratorT>, + adapted_t, + value_type const, + std::random_access_iterator_tag, + boost::use_default, + std::ptrdiff_t + > type; + }; + +#endif // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200 + +/////////////////////////////////////////////////////////////////////////////// +} /* namespace impl */ + + +/////////////////////////////////////////////////////////////////////////////// +// +// file_iterator +// +// Iterates through an opened file. +// +// The main iterator interface is implemented by the iterator_adaptors +// library, which wraps a conforming iterator interface around the +// impl::BaseIterator class. This class merely derives the iterator_adaptors +// generated class to implement the custom constructors and make_end() +// member function. +// +/////////////////////////////////////////////////////////////////////////////// + +template<typename CharT, typename BaseIteratorT> +class file_iterator + : public fileiter_impl::file_iter_generator<CharT, BaseIteratorT>::type, + public safe_bool<file_iterator<CharT, BaseIteratorT> > +{ +private: + typedef typename + fileiter_impl::file_iter_generator<CharT, BaseIteratorT>::type + base_t; + typedef typename + fileiter_impl::file_iter_generator<CharT, BaseIteratorT>::adapted_t + adapted_t; + +public: + file_iterator() + {} + + file_iterator(std::string const& fileName) + : base_t(adapted_t(fileName)) + {} + + file_iterator(const base_t& iter) + : base_t(iter) + {} + + inline file_iterator& operator=(const base_t& iter); + file_iterator make_end(void); + + // operator bool. This borrows a trick from boost::shared_ptr to avoid + // to interfere with arithmetic operations. + bool operator_bool(void) const + { return this->base(); } + +private: + friend class ::boost::iterator_core_access; + + typename base_t::reference dereference() const + { + return this->base_reference().get_cur_char(); + } + + void increment() + { + this->base_reference().next_char(); + } + + void decrement() + { + this->base_reference().prev_char(); + } + + void advance(typename base_t::difference_type n) + { + this->base_reference().advance(n); + } + + template < + typename OtherDerivedT, typename OtherIteratorT, + typename V, typename C, typename R, typename D + > + typename base_t::difference_type distance_to( + iterator_adaptor<OtherDerivedT, OtherIteratorT, V, C, R, D> + const &x) const + { + return x.base().distance(this->base_reference()); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} /* namespace BOOST_SPIRIT_CLASSIC_NS */ + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/spirit/home/classic/iterator/impl/file_iterator.ipp> /* implementation */ + +#endif /* BOOST_SPIRIT_FILE_ITERATOR_HPP */ + diff --git a/boost/spirit/home/classic/iterator/file_iterator_fwd.hpp b/boost/spirit/home/classic/iterator/file_iterator_fwd.hpp new file mode 100644 index 0000000000..fb732d56e6 --- /dev/null +++ b/boost/spirit/home/classic/iterator/file_iterator_fwd.hpp @@ -0,0 +1,39 @@ +/*============================================================================= + Copyright (c) 2006 Tobias Schwinger + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ + +#if !defined(BOOST_SPIRIT_FILE_ITERATOR_FWD_HPP) +#define BOOST_SPIRIT_FILE_ITERATOR_FWD_HPP + +#include <boost/spirit/home/classic/namespace.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + namespace fileiter_impl + { + template <typename CharT = char> + class std_file_iterator; + + // may never be defined -- so what... + template <typename CharT = char> + class mmap_file_iterator; + } + + // no defaults here -- too much dependencies + template < + typename CharT, + typename BaseIterator + > class file_iterator; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + diff --git a/boost/spirit/home/classic/iterator/fixed_size_queue.hpp b/boost/spirit/home/classic/iterator/fixed_size_queue.hpp new file mode 100644 index 0000000000..6efbf4c160 --- /dev/null +++ b/boost/spirit/home/classic/iterator/fixed_size_queue.hpp @@ -0,0 +1,402 @@ +/*============================================================================= + Copyright (c) 2001, Daniel C. Nuffer + Copyright (c) 2003, Hartmut Kaiser + 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 FIXED_SIZE_QUEUE +#define FIXED_SIZE_QUEUE + +#include <cstdlib> +#include <iterator> +#include <cstddef> + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/assert.hpp> // for BOOST_SPIRIT_ASSERT + +// FIXES for broken compilers +#include <boost/config.hpp> +#include <boost/iterator_adaptors.hpp> + +#define BOOST_SPIRIT_ASSERT_FSQ_SIZE \ + BOOST_SPIRIT_ASSERT(((m_tail + N + 1) - m_head) % (N+1) == m_size % (N+1)) \ + /**/ + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +namespace impl { + +#if !defined(BOOST_ITERATOR_ADAPTORS_VERSION) || \ + BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200 +#error "Please use at least Boost V1.31.0 while compiling the fixed_size_queue class!" +#else // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200 + +template <typename QueueT, typename T, typename PointerT> +class fsq_iterator +: public boost::iterator_adaptor< + fsq_iterator<QueueT, T, PointerT>, + PointerT, + T, + std::random_access_iterator_tag + > +{ +public: + typedef typename QueueT::position_t position; + typedef boost::iterator_adaptor< + fsq_iterator<QueueT, T, PointerT>, PointerT, T, + std::random_access_iterator_tag + > base_t; + + fsq_iterator() {} + fsq_iterator(position const &p_) : p(p_) {} + + position const &get_position() const { return p; } + +private: + friend class boost::iterator_core_access; + + typename base_t::reference dereference() const + { + return p.self->m_queue[p.pos]; + } + + void increment() + { + ++p.pos; + if (p.pos == QueueT::MAX_SIZE+1) + p.pos = 0; + } + + void decrement() + { + if (p.pos == 0) + p.pos = QueueT::MAX_SIZE; + else + --p.pos; + } + + template < + typename OtherDerivedT, typename OtherIteratorT, + typename V, typename C, typename R, typename D + > + bool equal(iterator_adaptor<OtherDerivedT, OtherIteratorT, V, C, R, D> + const &x) const + { + position const &rhs_pos = + static_cast<OtherDerivedT const &>(x).get_position(); + return (p.self == rhs_pos.self) && (p.pos == rhs_pos.pos); + } + + template < + typename OtherDerivedT, typename OtherIteratorT, + typename V, typename C, typename R, typename D + > + typename base_t::difference_type distance_to( + iterator_adaptor<OtherDerivedT, OtherIteratorT, V, C, R, D> + const &x) const + { + typedef typename base_t::difference_type diff_t; + + position const &p2 = + static_cast<OtherDerivedT const &>(x).get_position(); + std::size_t pos1 = p.pos; + std::size_t pos2 = p2.pos; + + // Undefined behaviour if the iterators come from different + // containers + BOOST_SPIRIT_ASSERT(p.self == p2.self); + + if (pos1 < p.self->m_head) + pos1 += QueueT::MAX_SIZE; + if (pos2 < p2.self->m_head) + pos2 += QueueT::MAX_SIZE; + + if (pos2 > pos1) + return diff_t(pos2 - pos1); + else + return -diff_t(pos1 - pos2); + } + + void advance(typename base_t::difference_type n) + { + // Notice that we don't care values of n that can + // wrap around more than one time, since it would + // be undefined behaviour anyway (going outside + // the begin/end range). Negative wrapping is a bit + // cumbersome because we don't want to case p.pos + // to signed. + if (n < 0) + { + n = -n; + if (p.pos < (std::size_t)n) + p.pos = QueueT::MAX_SIZE+1 - (n - p.pos); + else + p.pos -= n; + } + else + { + p.pos += n; + if (p.pos >= QueueT::MAX_SIZE+1) + p.pos -= QueueT::MAX_SIZE+1; + } + } + +private: + position p; +}; + +#endif // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200 + +/////////////////////////////////////////////////////////////////////////////// +} /* namespace impl */ + +template <typename T, std::size_t N> +class fixed_size_queue +{ +private: + struct position + { + fixed_size_queue* self; + std::size_t pos; + + position() : self(0), pos(0) {} + + // The const_cast here is just to avoid to have two different + // position structures for the const and non-const case. + // The const semantic is guaranteed by the iterator itself + position(const fixed_size_queue* s, std::size_t p) + : self(const_cast<fixed_size_queue*>(s)), pos(p) + {} + }; + +public: + // Declare the iterators + typedef impl::fsq_iterator<fixed_size_queue<T, N>, T, T*> iterator; + typedef impl::fsq_iterator<fixed_size_queue<T, N>, T const, T const*> + const_iterator; + typedef position position_t; + + friend class impl::fsq_iterator<fixed_size_queue<T, N>, T, T*>; + friend class impl::fsq_iterator<fixed_size_queue<T, N>, T const, T const*>; + + fixed_size_queue(); + fixed_size_queue(const fixed_size_queue& x); + fixed_size_queue& operator=(const fixed_size_queue& x); + ~fixed_size_queue(); + + void push_back(const T& e); + void push_front(const T& e); + void serve(T& e); + void pop_front(); + + bool empty() const + { + return m_size == 0; + } + + bool full() const + { + return m_size == N; + } + + iterator begin() + { + return iterator(position(this, m_head)); + } + + const_iterator begin() const + { + return const_iterator(position(this, m_head)); + } + + iterator end() + { + return iterator(position(this, m_tail)); + } + + const_iterator end() const + { + return const_iterator(position(this, m_tail)); + } + + std::size_t size() const + { + return m_size; + } + + T& front() + { + return m_queue[m_head]; + } + + const T& front() const + { + return m_queue[m_head]; + } + +private: + // Redefine the template parameters to avoid using partial template + // specialization on the iterator policy to extract N. + BOOST_STATIC_CONSTANT(std::size_t, MAX_SIZE = N); + + std::size_t m_head; + std::size_t m_tail; + std::size_t m_size; + T m_queue[N+1]; +}; + +template <typename T, std::size_t N> +inline +fixed_size_queue<T, N>::fixed_size_queue() + : m_head(0) + , m_tail(0) + , m_size(0) +{ + BOOST_SPIRIT_ASSERT(m_size <= N+1); + BOOST_SPIRIT_ASSERT_FSQ_SIZE; + BOOST_SPIRIT_ASSERT(m_head <= N+1); + BOOST_SPIRIT_ASSERT(m_tail <= N+1); +} + +template <typename T, std::size_t N> +inline +fixed_size_queue<T, N>::fixed_size_queue(const fixed_size_queue& x) + : m_head(x.m_head) + , m_tail(x.m_tail) + , m_size(x.m_size) +{ + copy(x.begin(), x.end(), begin()); + BOOST_SPIRIT_ASSERT(m_size <= N+1); + BOOST_SPIRIT_ASSERT_FSQ_SIZE; + BOOST_SPIRIT_ASSERT(m_head <= N+1); + BOOST_SPIRIT_ASSERT(m_tail <= N+1); +} + +template <typename T, std::size_t N> +inline fixed_size_queue<T, N>& +fixed_size_queue<T, N>::operator=(const fixed_size_queue& x) +{ + if (this != &x) + { + m_head = x.m_head; + m_tail = x.m_tail; + m_size = x.m_size; + copy(x.begin(), x.end(), begin()); + } + BOOST_SPIRIT_ASSERT(m_size <= N+1); + BOOST_SPIRIT_ASSERT_FSQ_SIZE; + BOOST_SPIRIT_ASSERT(m_head <= N+1); + BOOST_SPIRIT_ASSERT(m_tail <= N+1); + + return *this; +} + +template <typename T, std::size_t N> +inline +fixed_size_queue<T, N>::~fixed_size_queue() +{ + BOOST_SPIRIT_ASSERT(m_size <= N+1); + BOOST_SPIRIT_ASSERT_FSQ_SIZE; + BOOST_SPIRIT_ASSERT(m_head <= N+1); + BOOST_SPIRIT_ASSERT(m_tail <= N+1); +} + +template <typename T, std::size_t N> +inline void +fixed_size_queue<T, N>::push_back(const T& e) +{ + BOOST_SPIRIT_ASSERT(m_size <= N+1); + BOOST_SPIRIT_ASSERT_FSQ_SIZE; + BOOST_SPIRIT_ASSERT(m_head <= N+1); + BOOST_SPIRIT_ASSERT(m_tail <= N+1); + + BOOST_SPIRIT_ASSERT(!full()); + + m_queue[m_tail] = e; + ++m_size; + ++m_tail; + if (m_tail == N+1) + m_tail = 0; + + + BOOST_SPIRIT_ASSERT(m_size <= N+1); + BOOST_SPIRIT_ASSERT_FSQ_SIZE; + BOOST_SPIRIT_ASSERT(m_head <= N+1); + BOOST_SPIRIT_ASSERT(m_tail <= N+1); +} + +template <typename T, std::size_t N> +inline void +fixed_size_queue<T, N>::push_front(const T& e) +{ + BOOST_SPIRIT_ASSERT(m_size <= N+1); + BOOST_SPIRIT_ASSERT_FSQ_SIZE; + BOOST_SPIRIT_ASSERT(m_head <= N+1); + BOOST_SPIRIT_ASSERT(m_tail <= N+1); + + BOOST_SPIRIT_ASSERT(!full()); + + if (m_head == 0) + m_head = N; + else + --m_head; + + m_queue[m_head] = e; + ++m_size; + + BOOST_SPIRIT_ASSERT(m_size <= N+1); + BOOST_SPIRIT_ASSERT_FSQ_SIZE; + BOOST_SPIRIT_ASSERT(m_head <= N+1); + BOOST_SPIRIT_ASSERT(m_tail <= N+1); +} + + +template <typename T, std::size_t N> +inline void +fixed_size_queue<T, N>::serve(T& e) +{ + BOOST_SPIRIT_ASSERT(m_size <= N+1); + BOOST_SPIRIT_ASSERT_FSQ_SIZE; + BOOST_SPIRIT_ASSERT(m_head <= N+1); + BOOST_SPIRIT_ASSERT(m_tail <= N+1); + + e = m_queue[m_head]; + pop_front(); +} + + + +template <typename T, std::size_t N> +inline void +fixed_size_queue<T, N>::pop_front() +{ + BOOST_SPIRIT_ASSERT(m_size <= N+1); + BOOST_SPIRIT_ASSERT_FSQ_SIZE; + BOOST_SPIRIT_ASSERT(m_head <= N+1); + BOOST_SPIRIT_ASSERT(m_tail <= N+1); + + ++m_head; + if (m_head == N+1) + m_head = 0; + --m_size; + + BOOST_SPIRIT_ASSERT(m_size <= N+1); + BOOST_SPIRIT_ASSERT_FSQ_SIZE; + BOOST_SPIRIT_ASSERT(m_head <= N+1); + BOOST_SPIRIT_ASSERT(m_tail <= N+1); +} + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#undef BOOST_SPIRIT_ASSERT_FSQ_SIZE + +#endif diff --git a/boost/spirit/home/classic/iterator/impl/file_iterator.ipp b/boost/spirit/home/classic/iterator/impl/file_iterator.ipp new file mode 100644 index 0000000000..4227b69665 --- /dev/null +++ b/boost/spirit/home/classic/iterator/impl/file_iterator.ipp @@ -0,0 +1,467 @@ +/*============================================================================= + Copyright (c) 2003 Giovanni Bajo + Copyright (c) 2003 Martin Wille + Copyright (c) 2003 Hartmut Kaiser + 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_SPIRIT_FILE_ITERATOR_IPP +#define BOOST_SPIRIT_FILE_ITERATOR_IPP + +#ifdef BOOST_SPIRIT_FILEITERATOR_WINDOWS +# include <windows.h> +#endif + +#include <cstdio> +#include <boost/shared_ptr.hpp> + +#ifdef BOOST_SPIRIT_FILEITERATOR_WINDOWS +# include <boost/type_traits/remove_pointer.hpp> +#endif + +#ifdef BOOST_SPIRIT_FILEITERATOR_POSIX +# include <sys/types.h> // open, stat, mmap, munmap +# include <sys/stat.h> // stat +# include <fcntl.h> // open +# include <unistd.h> // stat, mmap, munmap +# include <sys/mman.h> // mmap, mmunmap +#endif + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +namespace fileiter_impl { + +/////////////////////////////////////////////////////////////////////////////// +// +// std_file_iterator +// +// Base class that implements iteration through a file using standard C +// stream library (fopen and friends). This class and the following are +// the base components on which the iterator is built (through the +// iterator adaptor library). +// +// The opened file stream (FILE) is held with a shared_ptr<>, whose +// custom deleter invokes fcose(). This makes the syntax of the class +// very easy, especially everything related to copying. +// +/////////////////////////////////////////////////////////////////////////////// + +template <typename CharT> +class std_file_iterator +{ +public: + typedef CharT value_type; + + std_file_iterator() + {} + + explicit std_file_iterator(std::string const& fileName) + { + using namespace std; + FILE* f = fopen(fileName.c_str(), "rb"); + + // If the file was opened, store it into + // the smart pointer. + if (f) + { + m_file.reset(f, fclose); + m_pos = 0; + m_eof = false; + update_char(); + } + } + + std_file_iterator(const std_file_iterator& iter) + { *this = iter; } + + std_file_iterator& operator=(const std_file_iterator& iter) + { + m_file = iter.m_file; + m_curChar = iter.m_curChar; + m_eof = iter.m_eof; + m_pos = iter.m_pos; + + return *this; + } + + // Nasty bug in Comeau up to 4.3.0.1, we need explicit boolean context + // for shared_ptr to evaluate correctly + operator bool() const + { return m_file ? true : false; } + + bool operator==(const std_file_iterator& iter) const + { + return (m_file == iter.m_file) && (m_eof == iter.m_eof) && + (m_pos == iter.m_pos); + } + + const CharT& get_cur_char(void) const + { + return m_curChar; + } + + void prev_char(void) + { + m_pos -= sizeof(CharT); + update_char(); + } + + void next_char(void) + { + m_pos += sizeof(CharT); + update_char(); + } + + void seek_end(void) + { + using namespace std; + fseek(m_file.get(), 0, SEEK_END); + m_pos = ftell(m_file.get()) / sizeof(CharT); + m_eof = true; + } + + void advance(std::ptrdiff_t n) + { + m_pos += n * sizeof(CharT); + update_char(); + } + + std::ptrdiff_t distance(const std_file_iterator& iter) const + { + return (std::ptrdiff_t)(m_pos - iter.m_pos) / sizeof(CharT); + } + +private: + boost::shared_ptr<std::FILE> m_file; + std::size_t m_pos; + CharT m_curChar; + bool m_eof; + + void update_char(void) + { + using namespace std; + if ((std::size_t)ftell(m_file.get()) != m_pos) + fseek(m_file.get(), m_pos, SEEK_SET); + + m_eof = (fread(&m_curChar, sizeof(CharT), 1, m_file.get()) < 1); + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// +// mmap_file_iterator +// +// File iterator for memory mapped files, for now implemented on Windows and +// POSIX platforms. This class has the same interface of std_file_iterator, +// and can be used in its place (in fact, it's the default for Windows and +// POSIX). +// +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// mmap_file_iterator, Windows version +#ifdef BOOST_SPIRIT_FILEITERATOR_WINDOWS +template <typename CharT> +class mmap_file_iterator +{ +public: + typedef CharT value_type; + + mmap_file_iterator() + : m_filesize(0), m_curChar(0) + {} + + explicit mmap_file_iterator(std::string const& fileName) + : m_filesize(0), m_curChar(0) + { + HANDLE hFile = ::CreateFileA( + fileName.c_str(), + GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + FILE_FLAG_SEQUENTIAL_SCAN, + NULL + ); + + if (hFile == INVALID_HANDLE_VALUE) + return; + + // Store the size of the file, it's used to construct + // the end iterator + m_filesize = ::GetFileSize(hFile, NULL); + + HANDLE hMap = ::CreateFileMapping( + hFile, + NULL, + PAGE_READONLY, + 0, 0, + NULL + ); + + if (hMap == NULL) + { + ::CloseHandle(hFile); + return; + } + + LPVOID pMem = ::MapViewOfFile( + hMap, + FILE_MAP_READ, + 0, 0, 0 + ); + + if (pMem == NULL) + { + ::CloseHandle(hMap); + ::CloseHandle(hFile); + return; + } + + // We hold both the file handle and the memory pointer. + // We can close the hMap handle now because Windows holds internally + // a reference to it since there is a view mapped. + ::CloseHandle(hMap); + + // It seems like we can close the file handle as well (because + // a reference is hold by the filemap object). + ::CloseHandle(hFile); + + // Store the handles inside the shared_ptr (with the custom destructors) + m_mem.reset(static_cast<CharT*>(pMem), ::UnmapViewOfFile); + + // Start of the file + m_curChar = m_mem.get(); + } + + mmap_file_iterator(const mmap_file_iterator& iter) + { *this = iter; } + + mmap_file_iterator& operator=(const mmap_file_iterator& iter) + { + m_curChar = iter.m_curChar; + m_mem = iter.m_mem; + m_filesize = iter.m_filesize; + + return *this; + } + + // Nasty bug in Comeau up to 4.3.0.1, we need explicit boolean context + // for shared_ptr to evaluate correctly + operator bool() const + { return m_mem ? true : false; } + + bool operator==(const mmap_file_iterator& iter) const + { return m_curChar == iter.m_curChar; } + + const CharT& get_cur_char(void) const + { return *m_curChar; } + + void next_char(void) + { m_curChar++; } + + void prev_char(void) + { m_curChar--; } + + void advance(std::ptrdiff_t n) + { m_curChar += n; } + + std::ptrdiff_t distance(const mmap_file_iterator& iter) const + { return m_curChar - iter.m_curChar; } + + void seek_end(void) + { + m_curChar = m_mem.get() + + (m_filesize / sizeof(CharT)); + } + +private: +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + typedef boost::remove_pointer<HANDLE>::type handle_t; +#else + typedef void handle_t; +#endif + + boost::shared_ptr<CharT> m_mem; + std::size_t m_filesize; + CharT* m_curChar; +}; + +#endif // BOOST_SPIRIT_FILEITERATOR_WINDOWS + +/////////////////////////////////////////////////////////////////////////////// +// mmap_file_iterator, POSIX version +#ifdef BOOST_SPIRIT_FILEITERATOR_POSIX +template <typename CharT> +class mmap_file_iterator +{ +private: + struct mapping + { + mapping(void *p, off_t len) + : data(p) + , size(len) + { } + + CharT const *begin() const + { + return static_cast<CharT *>(data); + } + + CharT const *end() const + { + return static_cast<CharT *>(data) + size/sizeof(CharT); + } + + ~mapping() + { + munmap(static_cast<char*>(data), size); + } + + private: + void *data; + off_t size; + }; + +public: + typedef CharT value_type; + + mmap_file_iterator() + : m_curChar(0) + {} + + explicit mmap_file_iterator(std::string const& file_name) + : m_curChar(0) + { + // open the file + int fd = open(file_name.c_str(), +#ifdef O_NOCTTY + O_NOCTTY | // if stdin was closed then opening a file + // would cause the file to become the controlling + // terminal if the filename refers to a tty. Setting + // O_NOCTTY inhibits this. +#endif + O_RDONLY); + + if (fd == -1) + return; + + // call fstat to find get information about the file just + // opened (size and file type) + struct stat stat_buf; + if ((fstat(fd, &stat_buf) != 0) || !S_ISREG(stat_buf.st_mode)) + { // if fstat returns an error or if the file isn't a + // regular file we give up. + close(fd); + return; + } + + // perform the actual mapping + void *p = mmap(0, stat_buf.st_size, PROT_READ, MAP_SHARED, fd, 0); + // it is safe to close() here. POSIX requires that the OS keeps a + // second handle to the file while the file is mmapped. + close(fd); + + if (p == MAP_FAILED) + return; + + mapping *m = 0; + try + { + m = new mapping(p, stat_buf.st_size); + } + catch(...) + { + munmap(static_cast<char*>(p), stat_buf.st_size); + throw; + } + + m_mem.reset(m); + + // Start of the file + m_curChar = m_mem->begin(); + } + + mmap_file_iterator(const mmap_file_iterator& iter) + { *this = iter; } + + mmap_file_iterator& operator=(const mmap_file_iterator& iter) + { + m_curChar = iter.m_curChar; + m_mem = iter.m_mem; + + return *this; + } + + // Nasty bug in Comeau up to 4.3.0.1, we need explicit boolean context + // for shared_ptr to evaluate correctly + operator bool() const + { return m_mem ? true : false; } + + bool operator==(const mmap_file_iterator& iter) const + { return m_curChar == iter.m_curChar; } + + const CharT& get_cur_char(void) const + { return *m_curChar; } + + void next_char(void) + { m_curChar++; } + + void prev_char(void) + { m_curChar--; } + + void advance(signed long n) + { m_curChar += n; } + + long distance(const mmap_file_iterator& iter) const + { return m_curChar - iter.m_curChar; } + + void seek_end(void) + { + m_curChar = m_mem->end(); + } + +private: + + boost::shared_ptr<mapping> m_mem; + CharT const* m_curChar; +}; + +#endif // BOOST_SPIRIT_FILEITERATOR_POSIX + +/////////////////////////////////////////////////////////////////////////////// +} /* namespace boost::spirit::fileiter_impl */ + +template <typename CharT, typename BaseIteratorT> +file_iterator<CharT,BaseIteratorT> +file_iterator<CharT,BaseIteratorT>::make_end(void) +{ + file_iterator iter(*this); + iter.base_reference().seek_end(); + return iter; +} + +template <typename CharT, typename BaseIteratorT> +file_iterator<CharT,BaseIteratorT>& +file_iterator<CharT,BaseIteratorT>::operator=(const base_t& iter) +{ + base_t::operator=(iter); + return *this; +} + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} /* namespace boost::spirit */ + + +#endif /* BOOST_SPIRIT_FILE_ITERATOR_IPP */ diff --git a/boost/spirit/home/classic/iterator/impl/position_iterator.ipp b/boost/spirit/home/classic/iterator/impl/position_iterator.ipp new file mode 100644 index 0000000000..d473af1a4b --- /dev/null +++ b/boost/spirit/home/classic/iterator/impl/position_iterator.ipp @@ -0,0 +1,138 @@ +/*============================================================================= + Copyright (c) 2002 Juan Carlos Arevalo-Baeza + Copyright (c) 2002-2006 Hartmut Kaiser + Copyright (c) 2003 Giovanni Bajo + 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 POSITION_ITERATOR_IPP +#define POSITION_ITERATOR_IPP + +#include <boost/config.hpp> +#include <boost/iterator_adaptors.hpp> +#include <boost/type_traits/add_const.hpp> +#include <boost/mpl/if.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/spirit/home/classic/core/nil.hpp> // for nil_t +#include <boost/detail/iterator.hpp> // for boost::detail::iterator_traits + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// +// position_policy<file_position_without_column> +// +// Specialization to handle file_position_without_column. Only take care of +// newlines since no column tracking is needed. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename String> +class position_policy<file_position_without_column_base<String> > { + +public: + void next_line(file_position_without_column_base<String>& pos) + { + ++pos.line; + } + + void set_tab_chars(unsigned int /*chars*/){} + void next_char(file_position_without_column_base<String>& /*pos*/) {} + void tabulation(file_position_without_column_base<String>& /*pos*/) {} +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// position_policy<file_position> +// +// Specialization to handle file_position. Track characters and tabulation +// to compute the current column correctly. +// +// Default tab size is 4. You can change this with the set_tabchars member +// of position_iterator. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename String> +class position_policy<file_position_base<String> > { + +public: + position_policy() + : m_CharsPerTab(4) + {} + + void next_line(file_position_base<String>& pos) + { + ++pos.line; + pos.column = 1; + } + + void set_tab_chars(unsigned int chars) + { + m_CharsPerTab = chars; + } + + void next_char(file_position_base<String>& pos) + { + ++pos.column; + } + + void tabulation(file_position_base<String>& pos) + { + pos.column += m_CharsPerTab - (pos.column - 1) % m_CharsPerTab; + } + +private: + unsigned int m_CharsPerTab; +}; + +/* namespace boost::spirit { */ namespace iterator_ { namespace impl { + +/////////////////////////////////////////////////////////////////////////////// +// +// position_iterator_base_generator +// +// Metafunction to generate the iterator type using boost::iterator_adaptors, +// hiding all the metaprogramming thunking code in it. It is used +// mainly to keep the public interface (position_iterator) cleanear. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename MainIterT, typename ForwardIterT, typename PositionT> +struct position_iterator_base_generator +{ +private: + typedef boost::detail::iterator_traits<ForwardIterT> traits; + typedef typename traits::value_type value_type; + typedef typename traits::iterator_category iter_category_t; + + // Position iterator is always a non-mutable iterator + typedef typename boost::add_const<value_type>::type const_value_type; + +public: + // Check if the MainIterT is nil. If it's nil, it means that the actual + // self type is position_iterator. Otherwise, it's a real type we + // must use + typedef typename boost::mpl::if_< + typename boost::is_same<MainIterT, nil_t>::type, + position_iterator<ForwardIterT, PositionT, nil_t>, + MainIterT + >::type main_iter_t; + + typedef boost::iterator_adaptor< + main_iter_t, + ForwardIterT, + const_value_type, + boost::forward_traversal_tag + > type; +}; + +}} + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} /* namespace boost::spirit::iterator_::impl */ + +#endif diff --git a/boost/spirit/home/classic/iterator/multi_pass.hpp b/boost/spirit/home/classic/iterator/multi_pass.hpp new file mode 100644 index 0000000000..ec8e01c976 --- /dev/null +++ b/boost/spirit/home/classic/iterator/multi_pass.hpp @@ -0,0 +1,1307 @@ +/*============================================================================= + Copyright (c) 2001, Daniel C. 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_ITERATOR_MULTI_PASS_HPP +#define BOOST_SPIRIT_ITERATOR_MULTI_PASS_HPP + +#include <boost/config.hpp> +#include <boost/throw_exception.hpp> +#include <deque> +#include <iterator> +#include <iostream> +#include <algorithm> // for std::swap +#include <exception> // for std::exception +#include <boost/limits.hpp> +#include <boost/iterator.hpp> + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/assert.hpp> // for BOOST_SPIRIT_ASSERT +#include <boost/spirit/home/classic/iterator/fixed_size_queue.hpp> +#include <boost/detail/iterator.hpp> // for boost::detail::iterator_traits + +#include <boost/spirit/home/classic/iterator/multi_pass_fwd.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +namespace impl { + template <typename T> + inline void mp_swap(T& t1, T& t2); +} + +namespace multi_pass_policies +{ + +/////////////////////////////////////////////////////////////////////////////// +// class ref_counted +// Implementation of an OwnershipPolicy used by multi_pass. +// +// Implementation modified from RefCounted class from the Loki library by +// Andrei Alexandrescu +/////////////////////////////////////////////////////////////////////////////// +class ref_counted +{ + protected: + ref_counted() + : count(new std::size_t(1)) + {} + + ref_counted(ref_counted const& x) + : count(x.count) + {} + + // clone is called when a copy of the iterator is made, so increment + // the ref-count. + void clone() + { + ++*count; + } + + // called when a copy is deleted. Decrement the ref-count. Return + // value of true indicates that the last copy has been released. + bool release() + { + if (!--*count) + { + delete count; + count = 0; + return true; + } + return false; + } + + void swap(ref_counted& x) + { + impl::mp_swap(count, x.count); + } + + public: + // returns true if there is only one iterator in existence. + // std_deque StoragePolicy will free it's buffered data if this + // returns true. + bool unique() const + { + return *count == 1; + } + + private: + std::size_t* count; +}; + +/////////////////////////////////////////////////////////////////////////////// +// class first_owner +// Implementation of an OwnershipPolicy used by multi_pass +// This ownership policy dictates that the first iterator created will +// determine the lifespan of the shared components. This works well for +// spirit, since no dynamic allocation of iterators is done, and all copies +// are make on the stack. +// +// There is a caveat about using this policy together with the std_deque +// StoragePolicy. Since first_owner always returns false from unique(), +// std_deque will only release the queued data if clear_queue() is called. +/////////////////////////////////////////////////////////////////////////////// +class first_owner +{ + protected: + first_owner() + : first(true) + {} + + first_owner(first_owner const&) + : first(false) + {} + + void clone() + { + } + + // return true to indicate deletion of resources + bool release() + { + return first; + } + + void swap(first_owner&) + { + // if we're the first, we still remain the first, even if assigned + // to, so don't swap first_. swap is only called from operator= + } + + public: + bool unique() const + { + return false; // no way to know, so always return false + } + + private: + bool first; +}; + +/////////////////////////////////////////////////////////////////////////////// +// class illegal_backtracking +// thrown by buf_id_check CheckingPolicy if an instance of an iterator is +// used after another one has invalidated the queue +/////////////////////////////////////////////////////////////////////////////// +class illegal_backtracking : public std::exception +{ +public: + + illegal_backtracking() throw() {} + ~illegal_backtracking() throw() {} + + virtual const char* + what() const throw() + { return "BOOST_SPIRIT_CLASSIC_NS::illegal_backtracking"; } +}; + +/////////////////////////////////////////////////////////////////////////////// +// class buf_id_check +// Implementation of the CheckingPolicy used by multi_pass +// This policy is most effective when used together with the std_deque +// StoragePolicy. +// If used with the fixed_size_queue StoragePolicy, it will not detect +// iterator derefereces that are out of the range of the queue. +/////////////////////////////////////////////////////////////////////////////// +class buf_id_check +{ + protected: + buf_id_check() + : shared_buf_id(new unsigned long(0)) + , buf_id(0) + {} + + buf_id_check(buf_id_check const& x) + : shared_buf_id(x.shared_buf_id) + , buf_id(x.buf_id) + {} + + // will be called from the destructor of the last iterator. + void destroy() + { + delete shared_buf_id; + shared_buf_id = 0; + } + + void swap(buf_id_check& x) + { + impl::mp_swap(shared_buf_id, x.shared_buf_id); + impl::mp_swap(buf_id, x.buf_id); + } + + // called to verify that everything is okay. + void check() const + { + if (buf_id != *shared_buf_id) + { + boost::throw_exception(illegal_backtracking()); + } + } + + // called from multi_pass::clear_queue, so we can increment the count + void clear_queue() + { + ++*shared_buf_id; + ++buf_id; + } + + private: + unsigned long* shared_buf_id; + unsigned long buf_id; +}; + +/////////////////////////////////////////////////////////////////////////////// +// class no_check +// Implementation of the CheckingPolicy used by multi_pass +// It does not do anything :-) +/////////////////////////////////////////////////////////////////////////////// +class no_check +{ + protected: + no_check() {} + no_check(no_check const&) {} + void destroy() {} + void swap(no_check&) {} + void check() const {} + void clear_queue() {} +}; + +/////////////////////////////////////////////////////////////////////////////// +// class std_deque +// Implementation of the StoragePolicy used by multi_pass +// This stores all data in a std::deque, and keeps an offset to the current +// position. It stores all the data unless there is only one +// iterator using the queue. +// Note: a position is used instead of an iterator, because a push_back on +// a deque can invalidate any iterators. +/////////////////////////////////////////////////////////////////////////////// +class std_deque +{ + public: + +template <typename ValueT> +class inner +{ + private: + + typedef std::deque<ValueT> queue_type; + queue_type* queuedElements; + mutable typename queue_type::size_type queuePosition; + + protected: + inner() + : queuedElements(new queue_type) + , queuePosition(0) + {} + + inner(inner const& x) + : queuedElements(x.queuedElements) + , queuePosition(x.queuePosition) + {} + + // will be called from the destructor of the last iterator. + void destroy() + { + BOOST_SPIRIT_ASSERT(NULL != queuedElements); + delete queuedElements; + queuedElements = 0; + } + + void swap(inner& x) + { + impl::mp_swap(queuedElements, x.queuedElements); + impl::mp_swap(queuePosition, x.queuePosition); + } + + // This is called when the iterator is dereferenced. It's a template + // method so we can recover the type of the multi_pass iterator + // and call unique and access the m_input data member. + template <typename MultiPassT> + static typename MultiPassT::reference dereference(MultiPassT const& mp) + { + if (mp.queuePosition == mp.queuedElements->size()) + { + // check if this is the only iterator + if (mp.unique()) + { + // free up the memory used by the queue. + if (mp.queuedElements->size() > 0) + { + mp.queuedElements->clear(); + mp.queuePosition = 0; + } + } + return mp.get_input(); + } + else + { + return (*mp.queuedElements)[mp.queuePosition]; + } + } + + // This is called when the iterator is incremented. It's a template + // method so we can recover the type of the multi_pass iterator + // and call unique and access the m_input data member. + template <typename MultiPassT> + static void increment(MultiPassT& mp) + { + if (mp.queuePosition == mp.queuedElements->size()) + { + // check if this is the only iterator + if (mp.unique()) + { + // free up the memory used by the queue. + if (mp.queuedElements->size() > 0) + { + mp.queuedElements->clear(); + mp.queuePosition = 0; + } + } + else + { + mp.queuedElements->push_back(mp.get_input()); + ++mp.queuePosition; + } + mp.advance_input(); + } + else + { + ++mp.queuePosition; + } + + } + + // called to forcibly clear the queue + void clear_queue() + { + queuedElements->clear(); + queuePosition = 0; + } + + // called to determine whether the iterator is an eof iterator + template <typename MultiPassT> + static bool is_eof(MultiPassT const& mp) + { + return mp.queuePosition == mp.queuedElements->size() && + mp.input_at_eof(); + } + + // called by operator== + bool equal_to(inner const& x) const + { + return queuePosition == x.queuePosition; + } + + // called by operator< + bool less_than(inner const& x) const + { + return queuePosition < x.queuePosition; + } +}; // class inner + +}; // class std_deque + + +/////////////////////////////////////////////////////////////////////////////// +// class fixed_size_queue +// Implementation of the StoragePolicy used by multi_pass +// fixed_size_queue keeps a circular buffer (implemented by +// BOOST_SPIRIT_CLASSIC_NS::fixed_size_queue class) that is size N+1 and stores N elements. +// It is up to the user to ensure that there is enough look ahead for their +// grammar. Currently there is no way to tell if an iterator is pointing +// to forgotten data. The leading iterator will put an item in the queue +// and remove one when it is incremented. No dynamic allocation is done, +// except on creation of the queue (fixed_size_queue constructor). +/////////////////////////////////////////////////////////////////////////////// +template < std::size_t N> +class fixed_size_queue +{ + public: + +template <typename ValueT> +class inner +{ + private: + + typedef BOOST_SPIRIT_CLASSIC_NS::fixed_size_queue<ValueT, N> queue_type; + queue_type * queuedElements; + mutable typename queue_type::iterator queuePosition; + + protected: + inner() + : queuedElements(new queue_type) + , queuePosition(queuedElements->begin()) + {} + + inner(inner const& x) + : queuedElements(x.queuedElements) + , queuePosition(x.queuePosition) + {} + + // will be called from the destructor of the last iterator. + void destroy() + { + BOOST_SPIRIT_ASSERT(NULL != queuedElements); + delete queuedElements; + queuedElements = 0; + } + + void swap(inner& x) + { + impl::mp_swap(queuedElements, x.queuedElements); + impl::mp_swap(queuePosition, x.queuePosition); + } + + // This is called when the iterator is dereferenced. It's a template + // method so we can recover the type of the multi_pass iterator + // and access the m_input data member. + template <typename MultiPassT> + static typename MultiPassT::reference dereference(MultiPassT const& mp) + { + if (mp.queuePosition == mp.queuedElements->end()) + { + return mp.get_input(); + } + else + { + return *mp.queuePosition; + } + } + + // This is called when the iterator is incremented. It's a template + // method so we can recover the type of the multi_pass iterator + // and access the m_input data member. + template <typename MultiPassT> + static void increment(MultiPassT& mp) + { + if (mp.queuePosition == mp.queuedElements->end()) + { + // don't let the queue get larger than N + if (mp.queuedElements->size() >= N) + mp.queuedElements->pop_front(); + + mp.queuedElements->push_back(mp.get_input()); + mp.advance_input(); + } + ++mp.queuePosition; + } + + // no-op + void clear_queue() + {} + + // called to determine whether the iterator is an eof iterator + template <typename MultiPassT> + static bool is_eof(MultiPassT const& mp) + { + return mp.queuePosition == mp.queuedElements->end() && + mp.input_at_eof(); + } + + // called by operator== + bool equal_to(inner const& x) const + { + return queuePosition == x.queuePosition; + } + + // called by operator< + bool less_than(inner const& x) const + { + return queuePosition < x.queuePosition; + } +}; // class inner + +}; // class fixed_size_queue + + +/////////////////////////////////////////////////////////////////////////////// +// class input_iterator +// Implementation of the InputPolicy used by multi_pass +// input_iterator encapsulates an input iterator of type InputT +/////////////////////////////////////////////////////////////////////////////// +class input_iterator +{ + public: + +template <typename InputT> +class inner +{ + private: + typedef + typename boost::detail::iterator_traits<InputT>::value_type + result_type; + + public: + typedef result_type value_type; + + private: + struct Data { + Data(InputT const &input_) + : input(input_), was_initialized(false) + {} + + InputT input; + value_type curtok; + bool was_initialized; + }; + + // Needed by compilers not implementing the resolution to DR45. For + // reference, see + // http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#45. + + friend struct Data; + + public: + typedef + typename boost::detail::iterator_traits<InputT>::difference_type + difference_type; + typedef + typename boost::detail::iterator_traits<InputT>::pointer + pointer; + typedef + typename boost::detail::iterator_traits<InputT>::reference + reference; + + protected: + inner() + : data(0) + {} + + inner(InputT x) + : data(new Data(x)) + {} + + inner(inner const& x) + : data(x.data) + {} + + void destroy() + { + delete data; + data = 0; + } + + bool same_input(inner const& x) const + { + return data == x.data; + } + + typedef + typename boost::detail::iterator_traits<InputT>::value_type + value_t; + void swap(inner& x) + { + impl::mp_swap(data, x.data); + } + + void ensure_initialized() const + { + if (data && !data->was_initialized) { + data->curtok = *data->input; // get the first token + data->was_initialized = true; + } + } + + public: + reference get_input() const + { + BOOST_SPIRIT_ASSERT(NULL != data); + ensure_initialized(); + return data->curtok; + } + + void advance_input() + { + BOOST_SPIRIT_ASSERT(NULL != data); + data->was_initialized = false; // should get the next token + ++data->input; + } + + bool input_at_eof() const + { + return !data || data->input == InputT(); + } + + private: + Data *data; +}; + +}; + +/////////////////////////////////////////////////////////////////////////////// +// class lex_input +// Implementation of the InputPolicy used by multi_pass +// lex_input gets tokens (ints) from yylex() +/////////////////////////////////////////////////////////////////////////////// +class lex_input +{ + public: + +template <typename InputT> +class inner +{ + public: + typedef int value_type; + typedef std::ptrdiff_t difference_type; + typedef int* pointer; + typedef int& reference; + + protected: + inner() + : curtok(new int(0)) + {} + + inner(InputT x) + : curtok(new int(x)) + {} + + inner(inner const& x) + : curtok(x.curtok) + {} + + void destroy() + { + delete curtok; + curtok = 0; + } + + bool same_input(inner const& x) const + { + return curtok == x.curtok; + } + + void swap(inner& x) + { + impl::mp_swap(curtok, x.curtok); + } + + public: + reference get_input() const + { + return *curtok; + } + + void advance_input() + { + extern int yylex(); + *curtok = yylex(); + } + + bool input_at_eof() const + { + return *curtok == 0; + } + + private: + int* curtok; + +}; + +}; + +/////////////////////////////////////////////////////////////////////////////// +// class functor_input +// Implementation of the InputPolicy used by multi_pass +// functor_input gets tokens from a functor +// Note: the functor must have a typedef for result_type +// It also must have a static variable of type result_type defined to +// represent eof that is called eof. +/////////////////////////////////////////////////////////////////////////////// +class functor_input +{ + public: + +template <typename FunctorT> +class inner +{ + typedef typename FunctorT::result_type result_type; + public: + typedef result_type value_type; + typedef std::ptrdiff_t difference_type; + typedef result_type* pointer; + typedef result_type& reference; + + protected: + inner() + : ftor(0) + , curtok(0) + {} + + inner(FunctorT const& x) + : ftor(new FunctorT(x)) + , curtok(new result_type((*ftor)())) + {} + + inner(inner const& x) + : ftor(x.ftor) + , curtok(x.curtok) + {} + + void destroy() + { + delete ftor; + ftor = 0; + delete curtok; + curtok = 0; + } + + bool same_input(inner const& x) const + { + return ftor == x.ftor; + } + + void swap(inner& x) + { + impl::mp_swap(curtok, x.curtok); + impl::mp_swap(ftor, x.ftor); + } + + public: + reference get_input() const + { + return *curtok; + } + + void advance_input() + { + if (curtok) { + *curtok = (*ftor)(); + } + } + + bool input_at_eof() const + { + return !curtok || *curtok == ftor->eof; + } + + FunctorT& get_functor() const + { + return *ftor; + } + + + private: + FunctorT* ftor; + result_type* curtok; + +}; + +}; + +} // namespace multi_pass_policies + +/////////////////////////////////////////////////////////////////////////////// +// iterator_base_creator +/////////////////////////////////////////////////////////////////////////////// + +namespace iterator_ { namespace impl { + +// Meta-function to generate a std::iterator<> base class for multi_pass. This +// is used mainly to improve conformance of compilers not supporting PTS +// and thus relying on inheritance to recognize an iterator. +// We are using boost::iterator<> because it offers an automatic workaround +// for broken std::iterator<> implementations. +template <typename InputPolicyT, typename InputT> +struct iterator_base_creator +{ + typedef typename InputPolicyT::BOOST_NESTED_TEMPLATE inner<InputT> input_t; + + typedef boost::iterator + < + std::forward_iterator_tag, + typename input_t::value_type, + typename input_t::difference_type, + typename input_t::pointer, + typename input_t::reference + > type; +}; + +}} + +/////////////////////////////////////////////////////////////////////////////// +// class template multi_pass +/////////////////////////////////////////////////////////////////////////////// + +// The default multi_pass instantiation uses a ref-counted std_deque scheme. +template +< + typename InputT, + typename InputPolicy, + typename OwnershipPolicy, + typename CheckingPolicy, + typename StoragePolicy +> +class multi_pass + : public OwnershipPolicy + , public CheckingPolicy + , public StoragePolicy::template inner< + typename InputPolicy::template inner<InputT>::value_type> + , public InputPolicy::template inner<InputT> + , public iterator_::impl::iterator_base_creator<InputPolicy, InputT>::type +{ + typedef OwnershipPolicy OP; + typedef CheckingPolicy CHP; + typedef typename StoragePolicy::template inner< + typename InputPolicy::template inner<InputT>::value_type> SP; + typedef typename InputPolicy::template inner<InputT> IP; + typedef typename + iterator_::impl::iterator_base_creator<InputPolicy, InputT>::type + IB; + + public: + typedef typename IB::value_type value_type; + typedef typename IB::difference_type difference_type; + typedef typename IB::reference reference; + typedef typename IB::pointer pointer; + typedef InputT iterator_type; + + multi_pass(); + explicit multi_pass(InputT input); + +#if BOOST_WORKAROUND(__GLIBCPP__, == 20020514) + multi_pass(int); +#endif // BOOST_WORKAROUND(__GLIBCPP__, == 20020514) + + ~multi_pass(); + + multi_pass(multi_pass const&); + multi_pass& operator=(multi_pass const&); + + void swap(multi_pass& x); + + reference operator*() const; + pointer operator->() const; + multi_pass& operator++(); + multi_pass operator++(int); + + void clear_queue(); + + bool operator==(const multi_pass& y) const; + bool operator<(const multi_pass& y) const; + + private: // helper functions + bool is_eof() const; +}; + +template +< + typename InputT, + typename InputPolicy, + typename OwnershipPolicy, + typename CheckingPolicy, + typename StoragePolicy +> +inline +multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>:: +multi_pass() + : OP() + , CHP() + , SP() + , IP() +{ +} + +template +< + typename InputT, + typename InputPolicy, + typename OwnershipPolicy, + typename CheckingPolicy, + typename StoragePolicy +> +inline +multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>:: +multi_pass(InputT input) + : OP() + , CHP() + , SP() + , IP(input) +{ +} + +#if BOOST_WORKAROUND(__GLIBCPP__, == 20020514) + // The standard library shipped with gcc-3.1 has a bug in + // bits/basic_string.tcc. It tries to use iter::iter(0) to + // construct an iterator. Ironically, this happens in sanity + // checking code that isn't required by the standard. + // The workaround is to provide an additional constructor that + // ignores its int argument and behaves like the default constructor. +template +< + typename InputT, + typename InputPolicy, + typename OwnershipPolicy, + typename CheckingPolicy, + typename StoragePolicy +> +inline +multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>:: +multi_pass(int) + : OP() + , CHP() + , SP() + , IP() +{ +} +#endif // BOOST_WORKAROUND(__GLIBCPP__, == 20020514) + +template +< + typename InputT, + typename InputPolicy, + typename OwnershipPolicy, + typename CheckingPolicy, + typename StoragePolicy +> +inline +multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>:: +~multi_pass() +{ + if (OP::release()) + { + CHP::destroy(); + SP::destroy(); + IP::destroy(); + } +} + +template +< + typename InputT, + typename InputPolicy, + typename OwnershipPolicy, + typename CheckingPolicy, + typename StoragePolicy +> +inline +multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>:: +multi_pass( + multi_pass const& x) + : OP(x) + , CHP(x) + , SP(x) + , IP(x) +{ + OP::clone(); +} + +template +< + typename InputT, + typename InputPolicy, + typename OwnershipPolicy, + typename CheckingPolicy, + typename StoragePolicy +> +inline +multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>& +multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>:: +operator=( + multi_pass const& x) +{ + multi_pass temp(x); + temp.swap(*this); + return *this; +} + +template +< + typename InputT, + typename InputPolicy, + typename OwnershipPolicy, + typename CheckingPolicy, + typename StoragePolicy +> +inline void +multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>:: +swap(multi_pass& x) +{ + OP::swap(x); + CHP::swap(x); + SP::swap(x); + IP::swap(x); +} + +template +< + typename InputT, + typename InputPolicy, + typename OwnershipPolicy, + typename CheckingPolicy, + typename StoragePolicy +> +inline +typename multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>:: +reference +multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>:: +operator*() const +{ + CHP::check(); + return SP::dereference(*this); +} + +template +< + typename InputT, + typename InputPolicy, + typename OwnershipPolicy, + typename CheckingPolicy, + typename StoragePolicy +> +inline +typename multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>:: +pointer +multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>:: +operator->() const +{ + return &(operator*()); +} + +template +< + typename InputT, + typename InputPolicy, + typename OwnershipPolicy, + typename CheckingPolicy, + typename StoragePolicy +> +inline +multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>& +multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>:: +operator++() +{ + CHP::check(); + SP::increment(*this); + return *this; +} + +template +< + typename InputT, + typename InputPolicy, + typename OwnershipPolicy, + typename CheckingPolicy, + typename StoragePolicy +> +inline +multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy> +multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>:: +operator++(int) +{ + multi_pass + < + InputT, + InputPolicy, + OwnershipPolicy, + CheckingPolicy, + StoragePolicy + > tmp(*this); + + ++*this; + + return tmp; +} + +template +< + typename InputT, + typename InputPolicy, + typename OwnershipPolicy, + typename CheckingPolicy, + typename StoragePolicy +> +inline void +multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>:: +clear_queue() +{ + SP::clear_queue(); + CHP::clear_queue(); +} + +template +< + typename InputT, + typename InputPolicy, + typename OwnershipPolicy, + typename CheckingPolicy, + typename StoragePolicy +> +inline bool +multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>:: +is_eof() const +{ + return SP::is_eof(*this); +} + +///// Comparisons +template +< + typename InputT, + typename InputPolicy, + typename OwnershipPolicy, + typename CheckingPolicy, + typename StoragePolicy +> +inline bool +multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>:: +operator==(const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, + StoragePolicy>& y) const +{ + bool is_eof_ = SP::is_eof(*this); + bool y_is_eof_ = SP::is_eof(y); + + if (is_eof_ && y_is_eof_) + { + return true; // both are EOF + } + else if (is_eof_ ^ y_is_eof_) + { + return false; // one is EOF, one isn't + } + else if (!IP::same_input(y)) + { + return false; + } + else + { + return SP::equal_to(y); + } +} + +template +< + typename InputT, + typename InputPolicy, + typename OwnershipPolicy, + typename CheckingPolicy, + typename StoragePolicy +> +inline bool +multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>:: +operator<(const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, + StoragePolicy>& y) const +{ + return SP::less_than(y); +} + +template +< + typename InputT, + typename InputPolicy, + typename OwnershipPolicy, + typename CheckingPolicy, + typename StoragePolicy +> +inline +bool operator!=( + const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, + StoragePolicy>& x, + const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, + StoragePolicy>& y) +{ + return !(x == y); +} + +template +< + typename InputT, + typename InputPolicy, + typename OwnershipPolicy, + typename CheckingPolicy, + typename StoragePolicy +> +inline +bool operator>( + const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, + StoragePolicy>& x, + const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, + StoragePolicy>& y) +{ + return y < x; +} + +template +< + typename InputT, + typename InputPolicy, + typename OwnershipPolicy, + typename CheckingPolicy, + typename StoragePolicy +> +inline +bool operator>=( + const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, + StoragePolicy>& x, + const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, + StoragePolicy>& y) +{ + return !(x < y); +} + +template +< + typename InputT, + typename InputPolicy, + typename OwnershipPolicy, + typename CheckingPolicy, + typename StoragePolicy +> +inline +bool operator<=( + const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, + StoragePolicy>& x, + const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, + StoragePolicy>& y) +{ + return !(y < x); +} + +///// Generator function +template <typename InputT> +inline multi_pass<InputT, + multi_pass_policies::input_iterator, multi_pass_policies::ref_counted, + multi_pass_policies::buf_id_check, multi_pass_policies::std_deque> +make_multi_pass(InputT i) +{ + return multi_pass<InputT, + multi_pass_policies::input_iterator, multi_pass_policies::ref_counted, + multi_pass_policies::buf_id_check, multi_pass_policies::std_deque>(i); +} + +// this could be a template typedef, since such a thing doesn't +// exist in C++, we'll use inheritance to accomplish the same thing. + +template <typename InputT, std::size_t N> +class look_ahead : + public multi_pass< + InputT, + multi_pass_policies::input_iterator, + multi_pass_policies::first_owner, + multi_pass_policies::no_check, + multi_pass_policies::fixed_size_queue<N> > +{ + typedef multi_pass< + InputT, + multi_pass_policies::input_iterator, + multi_pass_policies::first_owner, + multi_pass_policies::no_check, + multi_pass_policies::fixed_size_queue<N> > base_t; + public: + look_ahead() + : base_t() {} + + explicit look_ahead(InputT x) + : base_t(x) {} + + look_ahead(look_ahead const& x) + : base_t(x) {} + +#if BOOST_WORKAROUND(__GLIBCPP__, == 20020514) + look_ahead(int) // workaround for a bug in the library + : base_t() {} // shipped with gcc 3.1 +#endif // BOOST_WORKAROUND(__GLIBCPP__, == 20020514) + + // default generated operators destructor and assignment operator are okay. +}; + +template +< + typename InputT, + typename InputPolicy, + typename OwnershipPolicy, + typename CheckingPolicy, + typename StoragePolicy +> +void swap( + multi_pass< + InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy + > &x, + multi_pass< + InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy + > &y) +{ + x.swap(y); +} + +namespace impl { + + template <typename T> + inline void mp_swap(T& t1, T& t2) + { + using std::swap; + using BOOST_SPIRIT_CLASSIC_NS::swap; + swap(t1, t2); + } +} + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif // BOOST_SPIRIT_ITERATOR_MULTI_PASS_HPP + + diff --git a/boost/spirit/home/classic/iterator/multi_pass_fwd.hpp b/boost/spirit/home/classic/iterator/multi_pass_fwd.hpp new file mode 100644 index 0000000000..a212305ac2 --- /dev/null +++ b/boost/spirit/home/classic/iterator/multi_pass_fwd.hpp @@ -0,0 +1,47 @@ +/*============================================================================= + Copyright (c) 2006 Tobias Schwinger + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_ITERATOR_MULTI_PASS_FWD_HPP) +#define BOOST_SPIRIT_ITERATOR_MULTI_PASS_FWD_HPP + +#include <cstddef> + +#include <boost/spirit/home/classic/namespace.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + namespace multi_pass_policies + { + class ref_counted; + class first_owner; + class buf_id_check; + class no_check; + class std_deque; + template<std::size_t N> class fixed_size_queue; + class input_iterator; + class lex_input; + class functor_input; + } + + template + < + typename InputT, + typename InputPolicy = multi_pass_policies::input_iterator, + typename OwnershipPolicy = multi_pass_policies::ref_counted, + typename CheckingPolicy = multi_pass_policies::buf_id_check, + typename StoragePolicy = multi_pass_policies::std_deque + > + class multi_pass; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + diff --git a/boost/spirit/home/classic/iterator/position_iterator.hpp b/boost/spirit/home/classic/iterator/position_iterator.hpp new file mode 100644 index 0000000000..e352f883ae --- /dev/null +++ b/boost/spirit/home/classic/iterator/position_iterator.hpp @@ -0,0 +1,436 @@ +/*============================================================================= + Copyright (c) 2002 Juan Carlos Arevalo-Baeza + Copyright (c) 2002-2006 Hartmut Kaiser + Copyright (c) 2003 Giovanni Bajo + 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_POSITION_ITERATOR_HPP +#define BOOST_SPIRIT_POSITION_ITERATOR_HPP + +#include <string> +#include <boost/config.hpp> +#include <boost/concept_check.hpp> + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/iterator/position_iterator_fwd.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// +// file_position_without_column +// +// A structure to hold positional information. This includes the file, +// and the line number +// +/////////////////////////////////////////////////////////////////////////////// +template <typename String> +struct file_position_without_column_base { + String file; + int line; + + file_position_without_column_base(String const& file_ = String(), + int line_ = 1): + file (file_), + line (line_) + {} + + bool operator==(const file_position_without_column_base& fp) const + { return line == fp.line && file == fp.file; } +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// file_position +// +// This structure holds complete file position, including file name, +// line and column number +// +/////////////////////////////////////////////////////////////////////////////// +template <typename String> +struct file_position_base : public file_position_without_column_base<String> { + int column; + + file_position_base(String const& file_ = String(), + int line_ = 1, int column_ = 1): + file_position_without_column_base<String> (file_, line_), + column (column_) + {} + + bool operator==(const file_position_base& fp) const + { return column == fp.column && this->line == fp.line && this->file == fp.file; } +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// position_policy<> +// +// This template is the policy to handle the file position. It is specialized +// on the position type. Providing a custom file_position also requires +// providing a specialization of this class. +// +// Policy interface: +// +// Default constructor of the custom position class must be accessible. +// set_tab_chars(unsigned int chars) - Set the tabstop width +// next_char(PositionT& pos) - Notify that a new character has been +// processed +// tabulation(PositionT& pos) - Notify that a tab character has been +// processed +// next_line(PositionT& pos) - Notify that a new line delimiter has +// been reached. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename PositionT> class position_policy; + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} /* namespace BOOST_SPIRIT_CLASSIC_NS */ + + +// This must be included here for full compatibility with old MSVC +#include "boost/spirit/home/classic/iterator/impl/position_iterator.ipp" + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// +// position_iterator +// +// It wraps an iterator, and keeps track of the current position in the input, +// as it gets incremented. +// +// The wrapped iterator must be at least a Forward iterator. The position +// iterator itself will always be a non-mutable Forward iterator. +// +// In order to have begin/end iterators constructed, the end iterator must be +// empty constructed. Similar to what happens with stream iterators. The begin +// iterator must be constructed from both, the begin and end iterators of the +// wrapped iterator type. This is necessary to implement the lookahead of +// characters necessary to parse CRLF sequences. +// +// In order to extract the current positional data from the iterator, you may +// use the get_position member function. +// +// You can also use the set_position member function to reset the current +// position to something new. +// +// The structure that holds the current position can be customized through a +// template parameter, and the class position_policy must be specialized +// on the new type to define how to handle it. Currently, it's possible +// to choose between the file_position and file_position_without_column +// (which saves some overhead if managing current column is not required). +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(BOOST_ITERATOR_ADAPTORS_VERSION) || \ + BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200 +#error "Please use at least Boost V1.31.0 while compiling the position_iterator class!" +#else // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200 + +/////////////////////////////////////////////////////////////////////////////// +// +// Uses the newer iterator_adaptor version (should be released with +// Boost V1.31.0) +// +/////////////////////////////////////////////////////////////////////////////// +template < + typename ForwardIteratorT, + typename PositionT, + typename SelfT +> +class position_iterator +: public iterator_::impl::position_iterator_base_generator< + SelfT, + ForwardIteratorT, + PositionT + >::type, + public position_policy<PositionT> +{ +private: + + typedef position_policy<PositionT> position_policy_t; + typedef typename iterator_::impl::position_iterator_base_generator< + SelfT, + ForwardIteratorT, + PositionT + >::type base_t; + typedef typename iterator_::impl::position_iterator_base_generator< + SelfT, + ForwardIteratorT, + PositionT + >::main_iter_t main_iter_t; + +public: + + typedef PositionT position_t; + + position_iterator() + : _isend(true) + {} + + position_iterator( + const ForwardIteratorT& begin, + const ForwardIteratorT& end) + : base_t(begin), _end(end), _pos(PositionT()), _isend(begin == end) + {} + + template <typename FileNameT> + position_iterator( + const ForwardIteratorT& begin, + const ForwardIteratorT& end, + FileNameT fileName) + : base_t(begin), _end(end), _pos(PositionT(fileName)), + _isend(begin == end) + {} + + template <typename FileNameT, typename LineT> + position_iterator( + const ForwardIteratorT& begin, + const ForwardIteratorT& end, + FileNameT fileName, LineT line) + : base_t(begin), _end(end), _pos(PositionT(fileName, line)), + _isend(begin == end) + {} + + template <typename FileNameT, typename LineT, typename ColumnT> + position_iterator( + const ForwardIteratorT& begin, + const ForwardIteratorT& end, + FileNameT fileName, LineT line, ColumnT column) + : base_t(begin), _end(end), _pos(PositionT(fileName, line, column)), + _isend(begin == end) + {} + + position_iterator( + const ForwardIteratorT& begin, + const ForwardIteratorT& end, + const PositionT& pos) + : base_t(begin), _end(end), _pos(pos), _isend(begin == end) + {} + + position_iterator(const position_iterator& iter) + : base_t(iter.base()), position_policy_t(iter), + _end(iter._end), _pos(iter._pos), _isend(iter._isend) + {} + + position_iterator& operator=(const position_iterator& iter) + { + base_t::operator=(iter); + position_policy_t::operator=(iter); + _end = iter._end; + _pos = iter._pos; + _isend = iter._isend; + return *this; + } + + void set_position(PositionT const& newpos) { _pos = newpos; } + PositionT& get_position() { return _pos; } + PositionT const& get_position() const { return _pos; } + + void set_tabchars(unsigned int chars) + { + // This function (which comes from the position_policy) has a + // different name on purpose, to avoid messing with using + // declarations or qualified calls to access the base template + // function, which might break some compilers. + this->position_policy_t::set_tab_chars(chars); + } + +private: + friend class boost::iterator_core_access; + + void increment() + { + typename base_t::reference val = *(this->base()); + if (val == '\n') { + ++this->base_reference(); + this->next_line(_pos); + static_cast<main_iter_t &>(*this).newline(); + } + else if ( val == '\r') { + ++this->base_reference(); + if (this->base_reference() == _end || *(this->base()) != '\n') + { + this->next_line(_pos); + static_cast<main_iter_t &>(*this).newline(); + } + } + else if (val == '\t') { + this->tabulation(_pos); + ++this->base_reference(); + } + else { + this->next_char(_pos); + ++this->base_reference(); + } + + // The iterator is at the end only if it's the same + // of the + _isend = (this->base_reference() == _end); + } + + template < + typename OtherDerivedT, typename OtherIteratorT, + typename V, typename C, typename R, typename D + > + bool equal(iterator_adaptor<OtherDerivedT, OtherIteratorT, V, C, R, D> + const &x) const + { + OtherDerivedT const &rhs = static_cast<OtherDerivedT const &>(x); + bool x_is_end = rhs._isend; + + return (_isend == x_is_end) && (_isend || this->base() == rhs.base()); + } + +protected: + + void newline(void) + {} + + ForwardIteratorT _end; + PositionT _pos; + bool _isend; +}; + +#endif // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200 + +/////////////////////////////////////////////////////////////////////////////// +// +// position_iterator2 +// +// Equivalent to position_iterator, but it is able to extract the current +// line into a string. This is very handy for error reports. +// +// Notice that the footprint of this class is higher than position_iterator, +// (how much depends on how bulky the underlying iterator is), so it should +// be used only if necessary. +// +/////////////////////////////////////////////////////////////////////////////// + +template +< + typename ForwardIteratorT, + typename PositionT +> +class position_iterator2 + : public position_iterator + < + ForwardIteratorT, + PositionT, + position_iterator2<ForwardIteratorT, PositionT> + > +{ + typedef position_iterator + < + ForwardIteratorT, + PositionT, + position_iterator2<ForwardIteratorT, PositionT> // JDG 4-15-03 + > base_t; + +public: + typedef typename base_t::value_type value_type; + typedef PositionT position_t; + + position_iterator2() + {} + + position_iterator2( + const ForwardIteratorT& begin, + const ForwardIteratorT& end): + base_t(begin, end), + _startline(begin) + {} + + template <typename FileNameT> + position_iterator2( + const ForwardIteratorT& begin, + const ForwardIteratorT& end, + FileNameT file): + base_t(begin, end, file), + _startline(begin) + {} + + template <typename FileNameT, typename LineT> + position_iterator2( + const ForwardIteratorT& begin, + const ForwardIteratorT& end, + FileNameT file, LineT line): + base_t(begin, end, file, line), + _startline(begin) + {} + + template <typename FileNameT, typename LineT, typename ColumnT> + position_iterator2( + const ForwardIteratorT& begin, + const ForwardIteratorT& end, + FileNameT file, LineT line, ColumnT column): + base_t(begin, end, file, line, column), + _startline(begin) + {} + + position_iterator2( + const ForwardIteratorT& begin, + const ForwardIteratorT& end, + const PositionT& pos): + base_t(begin, end, pos), + _startline(begin) + {} + + position_iterator2(const position_iterator2& iter) + : base_t(iter), _startline(iter._startline) + {} + + position_iterator2& operator=(const position_iterator2& iter) + { + base_t::operator=(iter); + _startline = iter._startline; + return *this; + } + + ForwardIteratorT get_currentline_begin(void) const + { return _startline; } + + ForwardIteratorT get_currentline_end(void) const + { return get_endline(); } + + std::basic_string<value_type> get_currentline(void) const + { + return std::basic_string<value_type> + (get_currentline_begin(), get_currentline_end()); + } + +protected: + ForwardIteratorT _startline; + + friend class position_iterator<ForwardIteratorT, PositionT, + position_iterator2<ForwardIteratorT, PositionT> >; + + ForwardIteratorT get_endline() const + { + ForwardIteratorT endline = _startline; + while (endline != this->_end && *endline != '\r' && *endline != '\n') + { + ++endline; + } + return endline; + } + + void newline(void) + { _startline = this->base(); } +}; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif diff --git a/boost/spirit/home/classic/iterator/position_iterator_fwd.hpp b/boost/spirit/home/classic/iterator/position_iterator_fwd.hpp new file mode 100644 index 0000000000..f194e24cab --- /dev/null +++ b/boost/spirit/home/classic/iterator/position_iterator_fwd.hpp @@ -0,0 +1,60 @@ +/*============================================================================= + Copyright (c) 2006 Tobias Schwinger + Copyright (c) 2002-2006 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_POSITION_ITERATOR_FWD_HPP) +#define BOOST_SPIRIT_POSITION_ITERATOR_FWD_HPP + +#include <string> +#include <boost/detail/iterator.hpp> // for boost::detail::iterator_traits +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/nil.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + template <typename String = std::string> + struct file_position_base; + + typedef file_position_base<std::string> file_position; + + template <typename String = std::string> + struct file_position_without_column_base; + + typedef file_position_without_column_base<std::string> file_position_without_column; + + template < + typename ForwardIteratorT, + typename PositionT = file_position_base< + std::basic_string< + typename boost::detail::iterator_traits<ForwardIteratorT>::value_type + > + >, + typename SelfT = nil_t + > + class position_iterator; + + template + < + typename ForwardIteratorT, + typename PositionT = file_position_base< + std::basic_string< + typename boost::detail::iterator_traits<ForwardIteratorT>::value_type + > + > + > + class position_iterator2; + + template <typename PositionT> class position_policy; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + diff --git a/boost/spirit/home/classic/iterator/typeof.hpp b/boost/spirit/home/classic/iterator/typeof.hpp new file mode 100644 index 0000000000..23882cab64 --- /dev/null +++ b/boost/spirit/home/classic/iterator/typeof.hpp @@ -0,0 +1,94 @@ +/*============================================================================= + Copyright (c) 2006 Tobias Schwinger + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_ITERATOR_TYPEOF_HPP) +#define BOOST_SPIRIT_ITERATOR_TYPEOF_HPP + +#include <boost/typeof/typeof.hpp> +#include <boost/typeof/std/string.hpp> + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/iterator/multi_pass_fwd.hpp> +#include <boost/spirit/home/classic/iterator/file_iterator_fwd.hpp> +#include <boost/spirit/home/classic/iterator/position_iterator_fwd.hpp> + +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + // external (from core) + struct nil_t; + + // fixed_size_queue.hpp + template<typename T, std::size_t N> class fixed_size_queue; + template<typename QueueT, typename T, typename PointerT> + class fsq_iterator; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() + +#if !defined(BOOST_SPIRIT_NIL_T_TYPEOF_REGISTERED) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::nil_t) +# define BOOST_SPIRIT_NIL_T_TYPEOF_REGISTERED +#endif + + +// multi_pass.hpp (has forward header) + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::multi_pass,5) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::multi_pass_policies::ref_counted) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::multi_pass_policies::first_owner) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::multi_pass_policies::buf_id_check) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::multi_pass_policies::no_check) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::multi_pass_policies::std_deque) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::multi_pass_policies::fixed_size_queue,(BOOST_TYPEOF_INTEGRAL(std::size_t))) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::multi_pass_policies::input_iterator) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::multi_pass_policies::lex_input) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::multi_pass_policies::functor_input) + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::multi_pass,3) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::multi_pass,1) + + +// file_iterator.hpp + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::file_iterator,2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::fileiter_impl::std_file_iterator,1) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::fileiter_impl::mmap_file_iterator,1) + +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::fileiter_impl::std_file_iterator<char>) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::fileiter_impl::std_file_iterator<wchar_t>) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::fileiter_impl::mmap_file_iterator<char>) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::fileiter_impl::mmap_file_iterator<wchar_t>) + + +// fixed_size_queue.hpp + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::fixed_size_queue,(typename)(BOOST_TYPEOF_INTEGRAL(std::size_t))) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::fsq_iterator,3) + + +// position_iterator.hpp + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::position_iterator,3) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::position_iterator2,2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::position_policy,1) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::file_position_base,1) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::file_position_without_column_base,1) + +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::file_position) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::file_position_base<std::basic_string<wchar_t> >) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::file_position_without_column) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::file_position_without_column_base<std::basic_string<wchar_t> >) + +#endif + diff --git a/boost/spirit/home/classic/meta.hpp b/boost/spirit/home/classic/meta.hpp new file mode 100644 index 0000000000..bdb93c5bb0 --- /dev/null +++ b/boost/spirit/home/classic/meta.hpp @@ -0,0 +1,26 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001-2003 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_META_MAIN_HPP) +#define BOOST_SPIRIT_META_MAIN_HPP + +#include <boost/spirit/home/classic/version.hpp> + +/////////////////////////////////////////////////////////////////////////////// +// +// Master header for Spirit.Meta +// +/////////////////////////////////////////////////////////////////////////////// + +#include <boost/spirit/home/classic/meta/fundamental.hpp> +#include <boost/spirit/home/classic/meta/parser_traits.hpp> +#include <boost/spirit/home/classic/meta/as_parser.hpp> +#include <boost/spirit/home/classic/meta/traverse.hpp> + +#endif // BOOST_SPIRIT_CORE_MAIN_HPP + diff --git a/boost/spirit/home/classic/meta/as_parser.hpp b/boost/spirit/home/classic/meta/as_parser.hpp new file mode 100644 index 0000000000..c5cc82d643 --- /dev/null +++ b/boost/spirit/home/classic/meta/as_parser.hpp @@ -0,0 +1,113 @@ +/*============================================================================= + Copyright (c) 2002-2003 Joel de Guzman + Copyright (c) 2002-2003 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_AS_PARSER_HPP) +#define BOOST_SPIRIT_AS_PARSER_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/primitives/primitives.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // Helper templates to derive the parser type from an auxilliary type + // and to generate an object of the required parser type given an + // auxilliary object. Supported types to convert are parsers, + // single characters and character strings. + // + /////////////////////////////////////////////////////////////////////////// + namespace impl + { + template<typename T> + struct default_as_parser + { + typedef T type; + static type const& convert(type const& p) + { + return p; + } + }; + + struct char_as_parser + { + typedef chlit<char> type; + static type convert(char ch) + { + return type(ch); + } + }; + + struct wchar_as_parser + { + typedef chlit<wchar_t> type; + static type convert(wchar_t ch) + { + return type(ch); + } + }; + + struct string_as_parser + { + typedef strlit<char const*> type; + static type convert(char const* str) + { + return type(str); + } + }; + + struct wstring_as_parser + { + typedef strlit<wchar_t const*> type; + static type convert(wchar_t const* str) + { + return type(str); + } + }; + } + + template<typename T> + struct as_parser : impl::default_as_parser<T> {}; + + template<> + struct as_parser<char> : impl::char_as_parser {}; + + template<> + struct as_parser<wchar_t> : impl::wchar_as_parser {}; + + template<> + struct as_parser<char*> : impl::string_as_parser {}; + + template<> + struct as_parser<char const*> : impl::string_as_parser {}; + + template<> + struct as_parser<wchar_t*> : impl::wstring_as_parser {}; + + template<> + struct as_parser<wchar_t const*> : impl::wstring_as_parser {}; + + template<int N> + struct as_parser<char[N]> : impl::string_as_parser {}; + + template<int N> + struct as_parser<wchar_t[N]> : impl::wstring_as_parser {}; + + template<int N> + struct as_parser<char const[N]> : impl::string_as_parser {}; + + template<int N> + struct as_parser<wchar_t const[N]> : impl::wstring_as_parser {}; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif diff --git a/boost/spirit/home/classic/meta/fundamental.hpp b/boost/spirit/home/classic/meta/fundamental.hpp new file mode 100644 index 0000000000..c7fcf04492 --- /dev/null +++ b/boost/spirit/home/classic/meta/fundamental.hpp @@ -0,0 +1,56 @@ +/*============================================================================= + Copyright (c) 2002-2003 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_FUNDAMENTAL_HPP) +#define BOOST_SPIRIT_FUNDAMENTAL_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/meta/impl/fundamental.ipp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // Helper template for counting the number of nodes contained in a + // given parser type. + // All parser_category type parsers are counted as nodes. + // + /////////////////////////////////////////////////////////////////////////// + template <typename ParserT> + struct node_count { + + typedef typename ParserT::parser_category_t parser_category_t; + typedef typename impl::nodes<parser_category_t> + ::template count<ParserT, mpl::int_<0> > count_t; + + BOOST_STATIC_CONSTANT(int, value = count_t::value); + }; + + /////////////////////////////////////////////////////////////////////////// + // + // Helper template for counting the number of leaf nodes contained in a + // given parser type. + // Only plain_parser_category type parsers are counted as leaf nodes. + // + /////////////////////////////////////////////////////////////////////////// + template <typename ParserT> + struct leaf_count { + + typedef typename ParserT::parser_category_t parser_category_t; + typedef typename impl::leafs<parser_category_t> + ::template count<ParserT, mpl::int_<0> > count_t; + + BOOST_STATIC_CONSTANT(int, value = count_t::value); + }; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif // !defined(BOOST_SPIRIT_FUNDAMENTAL_HPP) diff --git a/boost/spirit/home/classic/meta/impl/fundamental.ipp b/boost/spirit/home/classic/meta/impl/fundamental.ipp new file mode 100644 index 0000000000..798f22b61a --- /dev/null +++ b/boost/spirit/home/classic/meta/impl/fundamental.ipp @@ -0,0 +1,309 @@ +/*============================================================================= + Copyright (c) 2002-2003 Hartmut Kaiser + 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) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_FUNDAMENTAL_IPP) +#define BOOST_SPIRIT_FUNDAMENTAL_IPP + +#include <boost/mpl/int.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +#if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300) + BOOST_SPIRIT_DEPENDENT_TEMPLATE_WRAPPER2(count_wrapper, count); +#endif // defined(BOOST_MSVC) && (BOOST_MSVC <= 1300) + +namespace impl +{ + /////////////////////////////////////////////////////////////////////////// + // + // Helper template for counting the number of nodes contained in a + // given parser type. + // All parser_category type parsers are counted as nodes. + // + /////////////////////////////////////////////////////////////////////////// + template <typename CategoryT> + struct nodes; + + template <> + struct nodes<plain_parser_category> { + + template <typename ParserT, typename LeafCountT> + struct count { + + // __BORLANDC__ == 0x0561 isn't happy with BOOST_STATIC_CONSTANT + enum { value = (LeafCountT::value + 1) }; + }; + }; + +#if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300) + + template <> + struct nodes<unary_parser_category> { + + template <typename ParserT, typename LeafCountT> + struct count { + + typedef typename ParserT::subject_t subject_t; + typedef typename subject_t::parser_category_t subject_category_t; + + typedef nodes<subject_category_t> nodes_t; + typedef typename count_wrapper<nodes_t> + ::template result_<subject_t, LeafCountT> count_t; + + BOOST_STATIC_CONSTANT(int, value = count_t::value + 1); + }; + }; + + template <> + struct nodes<action_parser_category> { + + template <typename ParserT, typename LeafCountT> + struct count { + + typedef typename ParserT::subject_t subject_t; + typedef typename subject_t::parser_category_t subject_category_t; + + typedef nodes<subject_category_t> nodes_t; + typedef typename count_wrapper<nodes_t> + ::template result_<subject_t, LeafCountT> count_t; + + BOOST_STATIC_CONSTANT(int, value = count_t::value + 1); + }; + }; + + template <> + struct nodes<binary_parser_category> { + + template <typename ParserT, typename LeafCountT> + struct count { + + typedef typename ParserT::left_t left_t; + typedef typename ParserT::right_t right_t; + typedef typename left_t::parser_category_t left_category_t; + typedef typename right_t::parser_category_t right_category_t; + + typedef nodes<left_category_t> left_nodes_t; + typedef typename count_wrapper<left_nodes_t> + ::template result_<left_t, LeafCountT> left_count_t; + + typedef nodes<right_category_t> right_nodes_t; + typedef typename count_wrapper<right_nodes_t> + ::template result_<right_t, LeafCountT> right_count_t; + + BOOST_STATIC_CONSTANT(int, + value = (left_count_t::value + right_count_t::value + 1)); + }; + }; + +#else + + template <> + struct nodes<unary_parser_category> { + + template <typename ParserT, typename LeafCountT> + struct count { + + typedef typename ParserT::subject_t subject_t; + typedef typename subject_t::parser_category_t subject_category_t; + + // __BORLANDC__ == 0x0561 isn't happy with BOOST_STATIC_CONSTANT + enum { value = (nodes<subject_category_t> + ::template count<subject_t, LeafCountT>::value + 1) }; + }; + }; + + template <> + struct nodes<action_parser_category> { + + template <typename ParserT, typename LeafCountT> + struct count { + + typedef typename ParserT::subject_t subject_t; + typedef typename subject_t::parser_category_t subject_category_t; + + // __BORLANDC__ == 0x0561 isn't happy with BOOST_STATIC_CONSTANT + enum { value = (nodes<subject_category_t> + ::template count<subject_t, LeafCountT>::value + 1) }; + }; + }; + + template <> + struct nodes<binary_parser_category> { + + template <typename ParserT, typename LeafCountT> + struct count { + + typedef typename ParserT::left_t left_t; + typedef typename ParserT::right_t right_t; + typedef typename left_t::parser_category_t left_category_t; + typedef typename right_t::parser_category_t right_category_t; + + typedef count self_t; + + // __BORLANDC__ == 0x0561 isn't happy with BOOST_STATIC_CONSTANT + enum { + leftcount = (nodes<left_category_t> + ::template count<left_t, LeafCountT>::value), + rightcount = (nodes<right_category_t> + ::template count<right_t, LeafCountT>::value), + value = ((self_t::leftcount) + (self_t::rightcount) + 1) + }; + }; + }; + +#endif + + /////////////////////////////////////////////////////////////////////////// + // + // Helper template for counting the number of leaf nodes contained in a + // given parser type. + // Only plain_parser_category type parsers are counted as leaf nodes. + // + /////////////////////////////////////////////////////////////////////////// + template <typename CategoryT> + struct leafs; + + template <> + struct leafs<plain_parser_category> { + + template <typename ParserT, typename LeafCountT> + struct count { + + // __BORLANDC__ == 0x0561 isn't happy with BOOST_STATIC_CONSTANT + enum { value = (LeafCountT::value + 1) }; + }; + }; + +#if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300) + + template <> + struct leafs<unary_parser_category> { + + template <typename ParserT, typename LeafCountT> + struct count { + + typedef typename ParserT::subject_t subject_t; + typedef typename subject_t::parser_category_t subject_category_t; + + typedef leafs<subject_category_t> nodes_t; + typedef typename count_wrapper<nodes_t> + ::template result_<subject_t, LeafCountT> count_t; + + BOOST_STATIC_CONSTANT(int, value = count_t::value); + }; + }; + + template <> + struct leafs<action_parser_category> { + + template <typename ParserT, typename LeafCountT> + struct count { + + typedef typename ParserT::subject_t subject_t; + typedef typename subject_t::parser_category_t subject_category_t; + + typedef leafs<subject_category_t> nodes_t; + typedef typename count_wrapper<nodes_t> + ::template result_<subject_t, LeafCountT> count_t; + + BOOST_STATIC_CONSTANT(int, value = count_t::value); + }; + }; + + template <> + struct leafs<binary_parser_category> { + + template <typename ParserT, typename LeafCountT> + struct count { + + typedef typename ParserT::left_t left_t; + typedef typename ParserT::right_t right_t; + typedef typename left_t::parser_category_t left_category_t; + typedef typename right_t::parser_category_t right_category_t; + + typedef leafs<left_category_t> left_nodes_t; + typedef typename count_wrapper<left_nodes_t> + ::template result_<left_t, LeafCountT> left_count_t; + + typedef leafs<right_category_t> right_nodes_t; + typedef typename count_wrapper<right_nodes_t> + ::template result_<right_t, LeafCountT> right_count_t; + + BOOST_STATIC_CONSTANT(int, + value = (left_count_t::value + right_count_t::value)); + }; + }; + +#else + + template <> + struct leafs<unary_parser_category> { + + template <typename ParserT, typename LeafCountT> + struct count { + + typedef typename ParserT::subject_t subject_t; + typedef typename subject_t::parser_category_t subject_category_t; + + // __BORLANDC__ == 0x0561 isn't happy with BOOST_STATIC_CONSTANT + enum { value = (leafs<subject_category_t> + ::template count<subject_t, LeafCountT>::value) }; + }; + }; + + template <> + struct leafs<action_parser_category> { + + template <typename ParserT, typename LeafCountT> + struct count { + + typedef typename ParserT::subject_t subject_t; + typedef typename subject_t::parser_category_t subject_category_t; + + // __BORLANDC__ == 0x0561 isn't happy with BOOST_STATIC_CONSTANT + enum { value = (leafs<subject_category_t> + ::template count<subject_t, LeafCountT>::value) }; + }; + }; + + template <> + struct leafs<binary_parser_category> { + + template <typename ParserT, typename LeafCountT> + struct count { + + typedef typename ParserT::left_t left_t; + typedef typename ParserT::right_t right_t; + typedef typename left_t::parser_category_t left_category_t; + typedef typename right_t::parser_category_t right_category_t; + + typedef count self_t; + + // __BORLANDC__ == 0x0561 isn't happy with BOOST_STATIC_CONSTANT + enum { + leftcount = (leafs<left_category_t> + ::template count<left_t, LeafCountT>::value), + rightcount = (leafs<right_category_t> + ::template count<right_t, LeafCountT>::value), + value = (self_t::leftcount + self_t::rightcount) + }; + }; + }; + +#endif + +} // namespace impl + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#endif // !defined(BOOST_SPIRIT_FUNDAMENTAL_IPP) diff --git a/boost/spirit/home/classic/meta/impl/parser_traits.ipp b/boost/spirit/home/classic/meta/impl/parser_traits.ipp new file mode 100644 index 0000000000..e648acd4d0 --- /dev/null +++ b/boost/spirit/home/classic/meta/impl/parser_traits.ipp @@ -0,0 +1,191 @@ +/*============================================================================= + Copyright (c) 2002-2003 Joel de Guzman + Copyright (c) 2002-2003 Hartmut Kaiser + Copyright (c) 2003 Martin Wille + 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) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_PARSER_TRAITS_IPP) +#define BOOST_SPIRIT_PARSER_TRAITS_IPP + +#include <boost/spirit/home/classic/core/composite/operators.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +namespace impl +{ + +#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + + /////////////////////////////////////////////////////////////////////////// + // + // from spirit 1.1 (copyright (c) 2001 Bruce Florman) + // various workarounds to support compile time decisions without partial + // template specialization whether a given type is an instance of a + // concrete parser type. + // + /////////////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////////////// + template <typename T> + struct parser_type_traits + { + // Determine at compile time (without partial specialization) + // whether a given type is an instance of the alternative<A,B> + + static T t(); + + typedef struct { char dummy[1]; } size1_t; + typedef struct { char dummy[2]; } size2_t; + typedef struct { char dummy[3]; } size3_t; + typedef struct { char dummy[4]; } size4_t; + typedef struct { char dummy[5]; } size5_t; + typedef struct { char dummy[6]; } size6_t; + typedef struct { char dummy[7]; } size7_t; + typedef struct { char dummy[8]; } size8_t; + typedef struct { char dummy[9]; } size9_t; + typedef struct { char dummy[10]; } size10_t; + + // the following functions need no implementation + template <typename A, typename B> + static size1_t test_(alternative<A, B> const&); + template <typename A, typename B> + static size2_t test_(sequence<A, B> const&); + template <typename A, typename B> + static size3_t test_(sequential_or<A, B> const&); + template <typename A, typename B> + static size4_t test_(intersection<A, B> const&); + template <typename A, typename B> + static size5_t test_(difference<A, B> const&); + template <typename A, typename B> + static size6_t test_(exclusive_or<A, B> const&); + template <typename S> + static size7_t test_(optional<S> const&); + template <typename S> + static size8_t test_(kleene_star<S> const&); + template <typename S> + static size9_t test_(positive<S> const&); + + static size10_t test_(...); + + BOOST_STATIC_CONSTANT(bool, + is_alternative = (sizeof(size1_t) == sizeof(test_(t()))) ); + BOOST_STATIC_CONSTANT(bool, + is_sequence = (sizeof(size2_t) == sizeof(test_(t()))) ); + BOOST_STATIC_CONSTANT(bool, + is_sequential_or = (sizeof(size3_t) == sizeof(test_(t()))) ); + BOOST_STATIC_CONSTANT(bool, + is_intersection = (sizeof(size4_t) == sizeof(test_(t()))) ); + BOOST_STATIC_CONSTANT(bool, + is_difference = (sizeof(size5_t) == sizeof(test_(t()))) ); + BOOST_STATIC_CONSTANT(bool, + is_exclusive_or = (sizeof(size6_t) == sizeof(test_(t()))) ); + BOOST_STATIC_CONSTANT(bool, + is_optional = (sizeof(size7_t) == sizeof(test_(t()))) ); + BOOST_STATIC_CONSTANT(bool, + is_kleene_star = (sizeof(size8_t) == sizeof(test_(t()))) ); + BOOST_STATIC_CONSTANT(bool, + is_positive = (sizeof(size9_t) == sizeof(test_(t()))) ); + }; + +#else + + /////////////////////////////////////////////////////////////////////////// + struct parser_type_traits_base { + + BOOST_STATIC_CONSTANT(bool, is_alternative = false); + BOOST_STATIC_CONSTANT(bool, is_sequence = false); + BOOST_STATIC_CONSTANT(bool, is_sequential_or = false); + BOOST_STATIC_CONSTANT(bool, is_intersection = false); + BOOST_STATIC_CONSTANT(bool, is_difference = false); + BOOST_STATIC_CONSTANT(bool, is_exclusive_or = false); + BOOST_STATIC_CONSTANT(bool, is_optional = false); + BOOST_STATIC_CONSTANT(bool, is_kleene_star = false); + BOOST_STATIC_CONSTANT(bool, is_positive = false); + }; + + template <typename ParserT> + struct parser_type_traits : public parser_type_traits_base { + + // no definition here, fallback for all not explicitly mentioned parser + // types + }; + + template <typename A, typename B> + struct parser_type_traits<alternative<A, B> > + : public parser_type_traits_base { + + BOOST_STATIC_CONSTANT(bool, is_alternative = true); + }; + + template <typename A, typename B> + struct parser_type_traits<sequence<A, B> > + : public parser_type_traits_base { + + BOOST_STATIC_CONSTANT(bool, is_sequence = true); + }; + + template <typename A, typename B> + struct parser_type_traits<sequential_or<A, B> > + : public parser_type_traits_base { + + BOOST_STATIC_CONSTANT(bool, is_sequential_or = true); + }; + + template <typename A, typename B> + struct parser_type_traits<intersection<A, B> > + : public parser_type_traits_base { + + BOOST_STATIC_CONSTANT(bool, is_intersection = true); + }; + + template <typename A, typename B> + struct parser_type_traits<difference<A, B> > + : public parser_type_traits_base { + + BOOST_STATIC_CONSTANT(bool, is_difference = true); + }; + + template <typename A, typename B> + struct parser_type_traits<exclusive_or<A, B> > + : public parser_type_traits_base { + + BOOST_STATIC_CONSTANT(bool, is_exclusive_or = true); + }; + + template <typename S> + struct parser_type_traits<optional<S> > + : public parser_type_traits_base { + + BOOST_STATIC_CONSTANT(bool, is_optional = true); + }; + + template <typename S> + struct parser_type_traits<kleene_star<S> > + : public parser_type_traits_base { + + BOOST_STATIC_CONSTANT(bool, is_kleene_star = true); + }; + + template <typename S> + struct parser_type_traits<positive<S> > + : public parser_type_traits_base { + + BOOST_STATIC_CONSTANT(bool, is_positive = true); + }; + +#endif // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) +} // namespace impl + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#endif // !defined(BOOST_SPIRIT_PARSER_TRAITS_IPP) diff --git a/boost/spirit/home/classic/meta/impl/refactoring.ipp b/boost/spirit/home/classic/meta/impl/refactoring.ipp new file mode 100644 index 0000000000..61cc6b57b1 --- /dev/null +++ b/boost/spirit/home/classic/meta/impl/refactoring.ipp @@ -0,0 +1,451 @@ +/*============================================================================= + Copyright (c) 2002-2003 Hartmut Kaiser + 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_SPIRIT_REFACTORING_IPP +#define BOOST_SPIRIT_REFACTORING_IPP + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// +// The struct 'self_nested_refactoring' is used to indicate, that the +// refactoring algorithm should be 'self-nested'. +// +// The struct 'non_nested_refactoring' is used to indicate, that no nesting +// of refactoring algorithms is reqired. +// +/////////////////////////////////////////////////////////////////////////////// + +struct non_nested_refactoring { typedef non_nested_refactoring embed_t; }; +struct self_nested_refactoring { typedef self_nested_refactoring embed_t; }; + +/////////////////////////////////////////////////////////////////////////////// +namespace impl { + +/////////////////////////////////////////////////////////////////////////////// +// +// Helper templates for refactoring parsers +// +/////////////////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////////////// + // + // refactor the left unary operand of a binary parser + // + // The refactoring should be done only if the left operand is an + // unary_parser_category parser. + // + /////////////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////////////// + template <typename CategoryT> + struct refactor_unary_nested { + + template < + typename ParserT, typename NestedT, + typename ScannerT, typename BinaryT + > + static typename parser_result<ParserT, ScannerT>::type + parse(ParserT const &, ScannerT const& scan, BinaryT const& binary, + NestedT const& /*nested_d*/) + { + return binary.parse(scan); + } + }; + + template <> + struct refactor_unary_nested<unary_parser_category> { + + template < + typename ParserT, typename ScannerT, typename BinaryT, + typename NestedT + > + static typename parser_result<ParserT, ScannerT>::type + parse(ParserT const &, ScannerT const& scan, BinaryT const& binary, + NestedT const& nested_d) + { + typedef typename BinaryT::parser_generator_t op_t; + typedef + typename BinaryT::left_t::parser_generator_t + unary_t; + + return + unary_t::generate( + nested_d[ + op_t::generate(binary.left().subject(), binary.right()) + ] + ).parse(scan); + } + }; + + /////////////////////////////////////////////////////////////////////////// + template <typename CategoryT> + struct refactor_unary_non_nested { + + template <typename ParserT, typename ScannerT, typename BinaryT> + static typename parser_result<ParserT, ScannerT>::type + parse(ParserT const &, ScannerT const& scan, BinaryT const& binary) + { + return binary.parse(scan); + } + }; + + template <> + struct refactor_unary_non_nested<unary_parser_category> { + + template <typename ParserT, typename ScannerT, typename BinaryT> + static typename parser_result<ParserT, ScannerT>::type + parse(ParserT const &, ScannerT const& scan, BinaryT const& binary) + { + typedef typename BinaryT::parser_generator_t op_t; + typedef + typename BinaryT::left_t::parser_generator_t + unary_t; + + return unary_t::generate( + op_t::generate(binary.left().subject(), binary.right()) + ).parse(scan); + } + }; + + /////////////////////////////////////////////////////////////////////////// + template <typename NestedT> + struct refactor_unary_type { + + template <typename ParserT, typename ScannerT, typename BinaryT> + static typename parser_result<ParserT, ScannerT>::type + parse(ParserT const &p, ScannerT const& scan, BinaryT const& binary, + NestedT const& nested_d) + { + typedef + typename BinaryT::left_t::parser_category_t + parser_category_t; + + return refactor_unary_nested<parser_category_t>:: + parse(p, scan, binary, nested_d); + } + }; + + template <> + struct refactor_unary_type<non_nested_refactoring> { + + template <typename ParserT, typename ScannerT, typename BinaryT> + static typename parser_result<ParserT, ScannerT>::type + parse(ParserT const &p, ScannerT const& scan, BinaryT const& binary, + non_nested_refactoring const&) + { + typedef + typename BinaryT::left_t::parser_category_t + parser_category_t; + + return refactor_unary_non_nested<parser_category_t>:: + parse(p, scan, binary); + } + + }; + + template <> + struct refactor_unary_type<self_nested_refactoring> { + + template <typename ParserT, typename ScannerT, typename BinaryT> + static typename parser_result<ParserT, ScannerT>::type + parse(ParserT const &p, ScannerT const& scan, BinaryT const& binary, + self_nested_refactoring const &nested_tag) + { + typedef + typename BinaryT::left_t::parser_category_t + parser_category_t; + typedef typename ParserT::parser_generator_t parser_generator_t; + + parser_generator_t nested_d(nested_tag); + return refactor_unary_nested<parser_category_t>:: + parse(p, scan, binary, nested_d); + } + + }; + + /////////////////////////////////////////////////////////////////////////// + // + // refactor the action on the left operand of a binary parser + // + // The refactoring should be done only if the left operand is an + // action_parser_category parser. + // + /////////////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////////////// + template <typename CategoryT> + struct refactor_action_nested { + + template < + typename ParserT, typename ScannerT, typename BinaryT, + typename NestedT + > + static typename parser_result<ParserT, ScannerT>::type + parse(ParserT const &, ScannerT const& scan, BinaryT const& binary, + NestedT const& nested_d) + { + return nested_d[binary].parse(scan); + } + }; + + template <> + struct refactor_action_nested<action_parser_category> { + + template < + typename ParserT, typename ScannerT, typename BinaryT, + typename NestedT + > + static typename parser_result<ParserT, ScannerT>::type + parse(ParserT const &, ScannerT const& scan, BinaryT const& binary, + NestedT const& nested_d) + { + typedef typename BinaryT::parser_generator_t binary_gen_t; + + return ( + nested_d[ + binary_gen_t::generate( + binary.left().subject(), + binary.right() + ) + ][binary.left().predicate()] + ).parse(scan); + } + }; + + /////////////////////////////////////////////////////////////////////////// + template <typename CategoryT> + struct refactor_action_non_nested { + + template <typename ParserT, typename ScannerT, typename BinaryT> + static typename parser_result<ParserT, ScannerT>::type + parse(ParserT const &, ScannerT const& scan, BinaryT const& binary) + { + return binary.parse(scan); + } + }; + + template <> + struct refactor_action_non_nested<action_parser_category> { + + template <typename ParserT, typename ScannerT, typename BinaryT> + static typename parser_result<ParserT, ScannerT>::type + parse(ParserT const &, ScannerT const& scan, BinaryT const& binary) + { + typedef typename BinaryT::parser_generator_t binary_gen_t; + + return ( + binary_gen_t::generate( + binary.left().subject(), + binary.right() + )[binary.left().predicate()] + ).parse(scan); + } + }; + + /////////////////////////////////////////////////////////////////////////// + template <typename NestedT> + struct refactor_action_type { + + template <typename ParserT, typename ScannerT, typename BinaryT> + static typename parser_result<ParserT, ScannerT>::type + parse(ParserT const &p, ScannerT const& scan, BinaryT const& binary, + NestedT const& nested_d) + { + typedef + typename BinaryT::left_t::parser_category_t + parser_category_t; + + return refactor_action_nested<parser_category_t>:: + parse(p, scan, binary, nested_d); + } + }; + + template <> + struct refactor_action_type<non_nested_refactoring> { + + template <typename ParserT, typename ScannerT, typename BinaryT> + static typename parser_result<ParserT, ScannerT>::type + parse(ParserT const &p, ScannerT const& scan, BinaryT const& binary, + non_nested_refactoring const&) + { + typedef + typename BinaryT::left_t::parser_category_t + parser_category_t; + + return refactor_action_non_nested<parser_category_t>:: + parse(p, scan, binary); + } + }; + + template <> + struct refactor_action_type<self_nested_refactoring> { + + template <typename ParserT, typename ScannerT, typename BinaryT> + static typename parser_result<ParserT, ScannerT>::type + parse(ParserT const &p, ScannerT const& scan, BinaryT const& binary, + self_nested_refactoring const &nested_tag) + { + typedef typename ParserT::parser_generator_t parser_generator_t; + typedef + typename BinaryT::left_t::parser_category_t + parser_category_t; + + parser_generator_t nested_d(nested_tag); + return refactor_action_nested<parser_category_t>:: + parse(p, scan, binary, nested_d); + } + }; + + /////////////////////////////////////////////////////////////////////////// + // + // refactor the action attached to a binary parser + // + // The refactoring should be done only if the given parser is an + // binary_parser_category parser. + // + /////////////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////////////// + template <typename CategoryT> + struct attach_action_nested { + + template < + typename ParserT, typename ScannerT, typename ActionT, + typename NestedT + > + static typename parser_result<ParserT, ScannerT>::type + parse(ParserT const &, ScannerT const& scan, ActionT const &action, + NestedT const& nested_d) + { + return action.parse(scan); + } + }; + + template <> + struct attach_action_nested<binary_parser_category> { + + template < + typename ParserT, typename ScannerT, typename ActionT, + typename NestedT + > + static typename parser_result<ParserT, ScannerT>::type + parse(ParserT const &, ScannerT const& scan, ActionT const &action, + NestedT const& nested_d) + { + typedef + typename ActionT::subject_t::parser_generator_t + binary_gen_t; + + return ( + binary_gen_t::generate( + nested_d[action.subject().left()[action.predicate()]], + nested_d[action.subject().right()[action.predicate()]] + ) + ).parse(scan); + } + }; + + /////////////////////////////////////////////////////////////////////////// + template <typename CategoryT> + struct attach_action_non_nested { + + template <typename ParserT, typename ScannerT, typename ActionT> + static typename parser_result<ParserT, ScannerT>::type + parse(ParserT const &, ScannerT const& scan, ActionT const &action) + { + return action.parse(scan); + } + }; + + template <> + struct attach_action_non_nested<binary_parser_category> { + + template <typename ParserT, typename ScannerT, typename ActionT> + static typename parser_result<ParserT, ScannerT>::type + parse(ParserT const &, ScannerT const& scan, ActionT const &action) + { + typedef + typename ActionT::subject_t::parser_generator_t + binary_gen_t; + + return ( + binary_gen_t::generate( + action.subject().left()[action.predicate()], + action.subject().right()[action.predicate()] + ) + ).parse(scan); + } + }; + + /////////////////////////////////////////////////////////////////////////// + template <typename NestedT> + struct attach_action_type { + + template <typename ParserT, typename ScannerT, typename ActionT> + static typename parser_result<ParserT, ScannerT>::type + parse(ParserT const &p, ScannerT const& scan, ActionT const& action, + NestedT const& nested_d) + { + typedef + typename ActionT::subject_t::parser_category_t + parser_category_t; + + return attach_action_nested<parser_category_t>:: + parse(p, scan, action, nested_d); + } + }; + + template <> + struct attach_action_type<non_nested_refactoring> { + + template <typename ParserT, typename ScannerT, typename ActionT> + static typename parser_result<ParserT, ScannerT>::type + parse(ParserT const &p, ScannerT const& scan, ActionT const &action, + non_nested_refactoring const&) + { + typedef + typename ActionT::subject_t::parser_category_t + parser_category_t; + + return attach_action_non_nested<parser_category_t>:: + parse(p, scan, action); + } + }; + + template <> + struct attach_action_type<self_nested_refactoring> { + + template <typename ParserT, typename ScannerT, typename ActionT> + static typename parser_result<ParserT, ScannerT>::type + parse(ParserT const &p, ScannerT const& scan, ActionT const &action, + self_nested_refactoring const& nested_tag) + { + typedef typename ParserT::parser_generator_t parser_generator_t; + typedef + typename ActionT::subject_t::parser_category_t + parser_category_t; + + parser_generator_t nested_d(nested_tag); + return attach_action_nested<parser_category_t>:: + parse(p, scan, action, nested_d); + } + }; + +} // namespace impl + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#endif + diff --git a/boost/spirit/home/classic/meta/impl/traverse.ipp b/boost/spirit/home/classic/meta/impl/traverse.ipp new file mode 100644 index 0000000000..3968230889 --- /dev/null +++ b/boost/spirit/home/classic/meta/impl/traverse.ipp @@ -0,0 +1,393 @@ +/*============================================================================= + Copyright (c) 2002-2003 Joel de Guzman + Copyright (c) 2002-2003 Hartmut Kaiser + 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) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_TRAVERSE_IPP) +#define BOOST_SPIRIT_TRAVERSE_IPP + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/spirit/home/classic/meta/fundamental.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +namespace impl +{ + + template <typename CategoryT> + struct traverse_post_order_return_category; + +} // namespace impl + +/////////////////////////////////////////////////////////////////////////////// +// +// Environment class for post_order_traversal +// +/////////////////////////////////////////////////////////////////////////////// + +template <int Level, int Node, int Index, int LastLeft> +struct traverse_post_order_env { + + BOOST_STATIC_CONSTANT(int, level = Level); + BOOST_STATIC_CONSTANT(int, node = Node); + BOOST_STATIC_CONSTANT(int, index = Index); + BOOST_STATIC_CONSTANT(int, lastleft = LastLeft); +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// traverse_post_order_return template +// +// This template is a helper for dispatching the calculation of a parser +// type result for a traversal level to the corresponding parser_category +// based specialization. +// +/////////////////////////////////////////////////////////////////////////////// + +template <typename MetaT, typename ParserT, typename EnvT> +struct traverse_post_order_return { + + typedef typename ParserT::parser_category_t parser_category_t; + typedef typename impl::traverse_post_order_return_category<parser_category_t> + ::template result<MetaT, ParserT, EnvT>::type type; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// parser_traversal_..._result templates +// +// These are metafunctions, which calculate the resulting parser type +// for all subparsers and feed these types to the user supplied +// metafunctions to get back the resulting parser type of this traversal +// level. +// +/////////////////////////////////////////////////////////////////////////////// + +template <typename MetaT, typename ParserT, typename EnvT> +struct parser_traversal_plain_result { + + typedef typename MetaT::template plain_result<ParserT, EnvT>::type type; +}; + +/////////////////////////////////////////////////////////////////////////////// +template <typename MetaT, typename UnaryT, typename SubjectT, typename EnvT> +struct parser_traversal_unary_result { + + typedef typename MetaT + ::template unary_result<UnaryT, SubjectT, EnvT>::type type; +}; + +/////////////////////////////////////////////////////////////////////////////// +template <typename MetaT, typename ActionT, typename SubjectT, typename EnvT> +struct parser_traversal_action_result { + + typedef typename MetaT + ::template action_result<ActionT, SubjectT, EnvT>::type type; +}; + +/////////////////////////////////////////////////////////////////////////////// +template < + typename MetaT, typename BinaryT, typename LeftT, + typename RightT, typename EnvT +> +struct parser_traversal_binary_result { + + BOOST_STATIC_CONSTANT(int, + thisnum = (node_count<BinaryT>::value + EnvT::lastleft-1)); + BOOST_STATIC_CONSTANT(int, + leftnum = (node_count<LeftT>::value + EnvT::lastleft-1)); + BOOST_STATIC_CONSTANT(int, + leafnum = (leaf_count<LeftT>::value + EnvT::index)); + + typedef parser_traversal_binary_result self_t; + + // left traversal environment and resulting parser type + typedef traverse_post_order_env< + (EnvT::level+1), (self_t::leftnum), (EnvT::index), (EnvT::lastleft) + > left_sub_env_t; + typedef typename traverse_post_order_return< + MetaT, LeftT, left_sub_env_t + >::type + left_t; + + // right traversal environment and resulting parser type + typedef traverse_post_order_env< + (EnvT::level+1), (self_t::thisnum-1), (self_t::leafnum), (self_t::leftnum+1) + > right_sub_env_t; + typedef typename traverse_post_order_return< + MetaT, RightT, right_sub_env_t + >::type + right_t; + + typedef typename MetaT::template binary_result< + BinaryT, left_t, right_t, EnvT + >::type + type; +}; + +/////////////////////////////////////////////////////////////////////////////// +namespace impl +{ + /////////////////////////////////////////////////////////////////////////// + // + // Meta functions, which dispatch the calculation of the return type of + // of the post_order traverse function to the result template of the + // corresponding parser_category based metafunction template. + // + /////////////////////////////////////////////////////////////////////////// + + template <typename CategoryT> + struct traverse_post_order_return_category; + + template <> + struct traverse_post_order_return_category<plain_parser_category> { + + template <typename MetaT, typename ParserT, typename EnvT> + struct result { + + typedef typename parser_traversal_plain_result< + MetaT, ParserT, EnvT + >::type + type; + }; + }; + + template <> + struct traverse_post_order_return_category<unary_parser_category> { + + template <typename MetaT, typename ParserT, typename EnvT> + struct result { + + typedef typename parser_traversal_unary_result< + MetaT, ParserT, typename ParserT::subject_t, EnvT + >::type + type; + }; + }; + + template <> + struct traverse_post_order_return_category<action_parser_category> { + + template <typename MetaT, typename ParserT, typename EnvT> + struct result { + + typedef typename parser_traversal_action_result< + MetaT, ParserT, typename ParserT::subject_t, EnvT + >::type + type; + }; + }; + + template <> + struct traverse_post_order_return_category<binary_parser_category> { + + template <typename MetaT, typename ParserT, typename EnvT> + struct result { + + typedef typename parser_traversal_binary_result< + MetaT, ParserT, typename ParserT::left_t, + typename ParserT::right_t, EnvT + >::type + type; + }; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // Post-order parser traversal + // + // The following templates contain the parser_category based code for + // + // - calculating the type of the resulting parser, which is to be + // returned from a level of traversal + // - traversing down the composite parser structure, this traversal + // returnes a new parser object + // + // Both tasks are delegated to the MetaT metafunction supplied by the + // user. + // + /////////////////////////////////////////////////////////////////////////// + + template <typename CategoryT> + struct traverse_post_order; + + template <> + struct traverse_post_order<plain_parser_category> { + + template <typename MetaT, typename ParserT, typename EnvT> + struct result { + + typedef + typename parser_traversal_plain_result<MetaT, ParserT, EnvT>::type + type; + }; + + template <typename MetaT, typename ParserT, typename EnvT> + static + typename parser_traversal_plain_result<MetaT, ParserT, EnvT>::type + generate(MetaT const &meta_, ParserT const &parser_, EnvT const &env) + { + return meta_.generate_plain(parser_, env); + } + }; + + template <> + struct traverse_post_order<unary_parser_category> { + + template < + typename MetaT, typename ParserT, typename SubjectT, typename EnvT + > + struct result { + + typedef typename parser_traversal_unary_result< + MetaT, ParserT, SubjectT, EnvT + >::type + type; + }; + + template <typename MetaT, typename ParserT, typename EnvT> + static + typename parser_traversal_unary_result< + MetaT, ParserT, + typename traverse_post_order_return< + MetaT, typename ParserT::subject_t, EnvT + >::type, + EnvT + >::type + generate(MetaT const &meta_, ParserT const &unary_, EnvT const &env) + { + typedef typename ParserT::subject_t subject_t; + typedef typename subject_t::parser_category_t subject_category_t; + + return meta_.generate_unary( + unary_, + traverse_post_order<subject_category_t>::generate(meta_, + unary_.subject(), + traverse_post_order_env< + EnvT::level+1, EnvT::node-1, EnvT::index, EnvT::lastleft + >() + ), + env + ); + } + }; + + template <> + struct traverse_post_order<action_parser_category> { + + template < + typename MetaT, typename ParserT, typename SubjectT, typename EnvT + > + struct result { + + typedef typename parser_traversal_action_result< + MetaT, ParserT, SubjectT, EnvT + >::type + type; + }; + + template <typename MetaT, typename ParserT, typename EnvT> + static + typename parser_traversal_action_result< + MetaT, ParserT, + typename traverse_post_order_return< + MetaT, typename ParserT::subject_t, EnvT + >::type, + EnvT + >::type + generate(MetaT const &meta_, ParserT const &action_, EnvT const &env) + { + typedef typename ParserT::subject_t subject_t; + typedef typename subject_t::parser_category_t subject_category_t; + + return meta_.generate_action( + action_, + traverse_post_order<subject_category_t>::generate(meta_, + action_.subject(), + traverse_post_order_env< + EnvT::level+1, EnvT::node-1, EnvT::index, EnvT::lastleft + >() + ), + env + ); + } + }; + + template <> + struct traverse_post_order<binary_parser_category> { + + template < + typename MetaT, typename ParserT, typename LeftT, + typename RightT, typename EnvT + > + struct result { + + typedef typename parser_traversal_binary_result< + MetaT, ParserT, LeftT, RightT, EnvT + >::type + type; + }; + + template <typename MetaT, typename ParserT, typename EnvT> + static + typename parser_traversal_binary_result< + MetaT, ParserT, + typename traverse_post_order_return< + MetaT, typename ParserT::left_t, EnvT + >::type, + typename traverse_post_order_return< + MetaT, typename ParserT::right_t, EnvT + >::type, + EnvT + >::type + generate(MetaT const &meta_, ParserT const &binary_, EnvT const& /*env*/) + { + typedef typename ParserT::left_t left_t; + typedef typename ParserT::right_t right_t; + typedef typename left_t::parser_category_t left_category_t; + typedef typename right_t::parser_category_t right_category_t; + + enum { + leftnum = (node_count<left_t>::value + EnvT::lastleft-1), + thisnum = (node_count<ParserT>::value + EnvT::lastleft-1), + rightnum = (thisnum-1), + leafnum = (leaf_count<left_t>::value + EnvT::index) + }; + + return meta_.generate_binary( + binary_, + traverse_post_order<left_category_t>::generate( + meta_, binary_.left(), + traverse_post_order_env< + EnvT::level+1, leftnum, EnvT::index, EnvT::lastleft + >() + ), + traverse_post_order<right_category_t>::generate( + meta_, binary_.right(), + traverse_post_order_env< + EnvT::level+1, rightnum, leafnum, leftnum+1 + >() + ), + traverse_post_order_env< + EnvT::level, thisnum, EnvT::index, EnvT::lastleft + >() + ); + } + }; + +} // namespace impl + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#endif // !defined(BOOST_SPIRIT_TRAVERSE_IPP) diff --git a/boost/spirit/home/classic/meta/parser_traits.hpp b/boost/spirit/home/classic/meta/parser_traits.hpp new file mode 100644 index 0000000000..618aade1d7 --- /dev/null +++ b/boost/spirit/home/classic/meta/parser_traits.hpp @@ -0,0 +1,320 @@ +/*============================================================================= + Copyright (c) 2002-2003 Joel de Guzman + Copyright (c) 2002-2003 Hartmut Kaiser + Copyright (c) 2003 Martin Wille + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_PARSER_TRAITS_HPP) +#define BOOST_SPIRIT_PARSER_TRAITS_HPP + +#include <boost/type_traits/is_base_and_derived.hpp> +#include <boost/static_assert.hpp> + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/meta/impl/parser_traits.ipp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// +// Parser traits templates +// +// Used to determine the type and several other characteristics of a given +// parser type. +// +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// +// The is_parser traits template can be used to tell wether a given +// class is a parser. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename T> +struct is_parser +{ + BOOST_STATIC_CONSTANT(bool, value = + (::boost::is_base_and_derived<parser<T>, T>::value)); + +// [JDG 2/3/03] simplified implementation by +// using boost::is_base_and_derived +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// The is_unary_composite traits template can be used to tell if a given +// parser is a unary parser as for instance kleene_star or optional. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename UnaryT> +struct is_unary_composite { + + BOOST_STATIC_CONSTANT(bool, value = (::boost::is_convertible< + typename UnaryT::parser_category_t, unary_parser_category>::value)); +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// The is_acction_parser traits template can be used to tell if a given +// parser is a action parser, i.e. it is a composite consisting of a +// auxilliary parser and an attached semantic action. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename ActionT> +struct is_action_parser { + + BOOST_STATIC_CONSTANT(bool, value = (::boost::is_convertible< + typename ActionT::parser_category_t, action_parser_category>::value)); +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// The is_binary_composite traits template can be used to tell if a given +// parser is a binary parser as for instance sequence or difference. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename BinaryT> +struct is_binary_composite { + + BOOST_STATIC_CONSTANT(bool, value = (::boost::is_convertible< + typename BinaryT::parser_category_t, binary_parser_category>::value)); +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// The is_composite_parser traits template can be used to tell if a given +// parser is a unary or a binary parser composite type. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename CompositeT> +struct is_composite_parser { + + BOOST_STATIC_CONSTANT(bool, value = ( + ::BOOST_SPIRIT_CLASSIC_NS::is_unary_composite<CompositeT>::value || + ::BOOST_SPIRIT_CLASSIC_NS::is_binary_composite<CompositeT>::value)); +}; + +/////////////////////////////////////////////////////////////////////////////// +template <typename ParserT> +struct is_alternative { + + BOOST_STATIC_CONSTANT(bool, value = ( + ::BOOST_SPIRIT_CLASSIC_NS::impl::parser_type_traits<ParserT>::is_alternative)); +}; + +template <typename ParserT> +struct is_sequence { + + BOOST_STATIC_CONSTANT(bool, value = ( + ::BOOST_SPIRIT_CLASSIC_NS::impl::parser_type_traits<ParserT>::is_sequence)); +}; + +template <typename ParserT> +struct is_sequential_or { + + BOOST_STATIC_CONSTANT(bool, value = ( + ::BOOST_SPIRIT_CLASSIC_NS::impl::parser_type_traits<ParserT>::is_sequential_or)); +}; + +template <typename ParserT> +struct is_intersection { + + BOOST_STATIC_CONSTANT(bool, value = ( + ::BOOST_SPIRIT_CLASSIC_NS::impl::parser_type_traits<ParserT>::is_intersection)); +}; + +template <typename ParserT> +struct is_difference { + + BOOST_STATIC_CONSTANT(bool, value = ( + ::BOOST_SPIRIT_CLASSIC_NS::impl::parser_type_traits<ParserT>::is_difference)); +}; + +template <typename ParserT> +struct is_exclusive_or { + + BOOST_STATIC_CONSTANT(bool, value = ( + ::BOOST_SPIRIT_CLASSIC_NS::impl::parser_type_traits<ParserT>::is_exclusive_or)); +}; + +template <typename ParserT> +struct is_optional { + + BOOST_STATIC_CONSTANT(bool, value = ( + ::BOOST_SPIRIT_CLASSIC_NS::impl::parser_type_traits<ParserT>::is_optional)); +}; + +template <typename ParserT> +struct is_kleene_star { + + BOOST_STATIC_CONSTANT(bool, value = ( + ::BOOST_SPIRIT_CLASSIC_NS::impl::parser_type_traits<ParserT>::is_kleene_star)); +}; + +template <typename ParserT> +struct is_positive { + + BOOST_STATIC_CONSTANT(bool, value = ( + ::BOOST_SPIRIT_CLASSIC_NS::impl::parser_type_traits<ParserT>::is_positive)); +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// Parser extraction templates +// +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// +// The unary_subject template can be used to return the type of the +// parser used as the subject of an unary parser. +// If the parser under inspection is not an unary type parser the compilation +// will fail. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename UnaryT> +struct unary_subject { + + BOOST_STATIC_ASSERT(BOOST_SPIRIT_CLASSIC_NS::is_unary_composite<UnaryT>::value); + typedef typename UnaryT::subject_t type; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// The get_unary_subject template function returns the parser object, which +// is used as the subject of an unary parser. +// If the parser under inspection is not an unary type parser the compilation +// will fail. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename UnaryT> +inline typename unary_subject<UnaryT>::type const & +get_unary_subject(UnaryT const &unary_) +{ + BOOST_STATIC_ASSERT(::BOOST_SPIRIT_CLASSIC_NS::is_unary_composite<UnaryT>::value); + return unary_.subject(); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// The binary_left_subject and binary_right_subject templates can be used to +// return the types of the parsers used as the left and right subject of an +// binary parser. +// If the parser under inspection is not a binary type parser the compilation +// will fail. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename BinaryT> +struct binary_left_subject { + + BOOST_STATIC_ASSERT(::BOOST_SPIRIT_CLASSIC_NS::is_binary_composite<BinaryT>::value); + typedef typename BinaryT::left_t type; +}; + +template <typename BinaryT> +struct binary_right_subject { + + BOOST_STATIC_ASSERT(::BOOST_SPIRIT_CLASSIC_NS::is_binary_composite<BinaryT>::value); + typedef typename BinaryT::right_t type; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// The get_binary_left_subject and get_binary_right_subject template functions +// return the parser object, which is used as the left or right subject of a +// binary parser. +// If the parser under inspection is not a binary type parser the compilation +// will fail. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename BinaryT> +inline typename binary_left_subject<BinaryT>::type const & +get_binary_left_subject(BinaryT const &binary_) +{ + BOOST_STATIC_ASSERT(::BOOST_SPIRIT_CLASSIC_NS::is_binary_composite<BinaryT>::value); + return binary_.left(); +} + +template <typename BinaryT> +inline typename binary_right_subject<BinaryT>::type const & +get_binary_right_subject(BinaryT const &binary_) +{ + BOOST_STATIC_ASSERT(::BOOST_SPIRIT_CLASSIC_NS::is_binary_composite<BinaryT>::value); + return binary_.right(); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// The action_subject template can be used to return the type of the +// parser used as the subject of an action parser. +// If the parser under inspection is not an action type parser the compilation +// will fail. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename ActionT> +struct action_subject { + + BOOST_STATIC_ASSERT(::BOOST_SPIRIT_CLASSIC_NS::is_action_parser<ActionT>::value); + typedef typename ActionT::subject_t type; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// The get_action_subject template function returns the parser object, which +// is used as the subject of an action parser. +// If the parser under inspection is not an action type parser the compilation +// will fail. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename ActionT> +inline typename action_subject<ActionT>::type const & +get_action_subject(ActionT const &action_) +{ + BOOST_STATIC_ASSERT(::BOOST_SPIRIT_CLASSIC_NS::is_action_parser<ActionT>::value); + return action_.subject(); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// The semantic_action template can be used to return the type of the +// attached semantic action of an action parser. +// If the parser under inspection is not an action type parser the compilation +// will fail. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename ActionT> +struct semantic_action { + + BOOST_STATIC_ASSERT(::BOOST_SPIRIT_CLASSIC_NS::is_action_parser<ActionT>::value); + typedef typename ActionT::predicate_t type; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// The get_semantic_action template function returns the attached semantic +// action of an action parser. +// If the parser under inspection is not an action type parser the compilation +// will fail. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename ActionT> +inline typename semantic_action<ActionT>::type const & +get_semantic_action(ActionT const &action_) +{ + BOOST_STATIC_ASSERT(::BOOST_SPIRIT_CLASSIC_NS::is_action_parser<ActionT>::value); + return action_.predicate(); +} + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif // !defined(BOOST_SPIRIT_PARSER_TRAITS_HPP) diff --git a/boost/spirit/home/classic/meta/refactoring.hpp b/boost/spirit/home/classic/meta/refactoring.hpp new file mode 100644 index 0000000000..e5d45f9297 --- /dev/null +++ b/boost/spirit/home/classic/meta/refactoring.hpp @@ -0,0 +1,287 @@ +/*============================================================================= + Copyright (c) 2002-2003 Hartmut Kaiser + 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_REFACTORING_HPP +#define BOOST_SPIRIT_REFACTORING_HPP + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/static_assert.hpp> +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/meta/as_parser.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/core/composite/composite.hpp> +#include <boost/spirit/home/classic/meta/impl/refactoring.ipp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(push) +#pragma warning(disable:4512) //assignment operator could not be generated +#endif + +/////////////////////////////////////////////////////////////////////////////// +// +// refactor_unary_parser class +// +// This helper template allows to attach an unary operation to a newly +// constructed parser, which combines the subject of the left operand of +// the original given parser (BinaryT) with the right operand of the +// original binary parser through the original binary operation and +// rewraps the resulting parser with the original unary operator. +// +// For instance given the parser: +// *some_parser - another_parser +// +// will be refactored to: +// *(some_parser - another_parser) +// +// If the parser to refactor is not a unary parser, no refactoring is done +// at all. +// +// The original parser should be a binary_parser_category parser, +// else the compilation will fail +// +/////////////////////////////////////////////////////////////////////////////// + +template <typename NestedT = non_nested_refactoring> +class refactor_unary_gen; + +template <typename BinaryT, typename NestedT = non_nested_refactoring> +class refactor_unary_parser : + public parser<refactor_unary_parser<BinaryT, NestedT> > { + +public: + // the parser to refactor has to be at least a binary_parser_category + // parser + BOOST_STATIC_ASSERT(( + boost::is_convertible<typename BinaryT::parser_category_t, + binary_parser_category>::value + )); + + refactor_unary_parser(BinaryT const& binary_, NestedT const& nested_) + : binary(binary_), nested(nested_) {} + + typedef refactor_unary_parser<BinaryT, NestedT> self_t; + typedef refactor_unary_gen<NestedT> parser_generator_t; + typedef typename BinaryT::left_t::parser_category_t parser_category_t; + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + return impl::refactor_unary_type<NestedT>:: + parse(*this, scan, binary, nested); + } + +private: + typename as_parser<BinaryT>::type::embed_t binary; + typename NestedT::embed_t nested; +}; + +////////////////////////////////// +template <typename NestedT> +class refactor_unary_gen { + +public: + typedef refactor_unary_gen<NestedT> embed_t; + + refactor_unary_gen(NestedT const& nested_ = non_nested_refactoring()) + : nested(nested_) {} + + template <typename ParserT> + refactor_unary_parser<ParserT, NestedT> + operator[](parser<ParserT> const& subject) const + { + return refactor_unary_parser<ParserT, NestedT> + (subject.derived(), nested); + } + +private: + typename NestedT::embed_t nested; +}; + +const refactor_unary_gen<> refactor_unary_d = refactor_unary_gen<>(); + +/////////////////////////////////////////////////////////////////////////////// +// +// refactor_action_parser class +// +// This helper template allows to attach an action taken from the left +// operand of the given binary parser to a newly constructed parser, +// which combines the subject of the left operand of the original binary +// parser with the right operand of the original binary parser by means of +// the original binary operator parser. +// +// For instance the parser: +// some_parser[some_attached_functor] - another_parser +// +// will be refactored to: +// (some_parser - another_parser)[some_attached_functor] +// +// If the left operand to refactor is not an action parser, no refactoring +// is done at all. +// +// The original parser should be a binary_parser_category parser, +// else the compilation will fail +// +/////////////////////////////////////////////////////////////////////////////// + +template <typename NestedT = non_nested_refactoring> +class refactor_action_gen; + +template <typename BinaryT, typename NestedT = non_nested_refactoring> +class refactor_action_parser : + public parser<refactor_action_parser<BinaryT, NestedT> > { + +public: + // the parser to refactor has to be at least a binary_parser_category + // parser + BOOST_STATIC_ASSERT(( + boost::is_convertible<typename BinaryT::parser_category_t, + binary_parser_category>::value + )); + + refactor_action_parser(BinaryT const& binary_, NestedT const& nested_) + : binary(binary_), nested(nested_) {} + + typedef refactor_action_parser<BinaryT, NestedT> self_t; + typedef refactor_action_gen<NestedT> parser_generator_t; + typedef typename BinaryT::left_t::parser_category_t parser_category_t; + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + return impl::refactor_action_type<NestedT>:: + parse(*this, scan, binary, nested); + } + +private: + typename as_parser<BinaryT>::type::embed_t binary; + typename NestedT::embed_t nested; +}; + +////////////////////////////////// +template <typename NestedT> +class refactor_action_gen { + +public: + typedef refactor_action_gen<NestedT> embed_t; + + refactor_action_gen(NestedT const& nested_ = non_nested_refactoring()) + : nested(nested_) {} + + template <typename ParserT> + refactor_action_parser<ParserT, NestedT> + operator[](parser<ParserT> const& subject) const + { + return refactor_action_parser<ParserT, NestedT> + (subject.derived(), nested); + } + +private: + typename NestedT::embed_t nested; +}; + +const refactor_action_gen<> refactor_action_d = refactor_action_gen<>(); + +/////////////////////////////////////////////////////////////////////////////// +// +// attach_action_parser class +// +// This helper template allows to attach an action given separately +// to to all parsers, out of which the given parser is constructed and +// reconstructs a new parser having the same structure. +// +// For instance the parser: +// (some_parser >> another_parser)[some_attached_functor] +// +// will be refactored to: +// some_parser[some_attached_functor] +// >> another_parser[some_attached_functor] +// +// The original parser should be a action_parser_category parser, +// else the compilation will fail +// +// If the parser, to which the action is attached is not an binary parser, +// no refactoring is done at all. +// +/////////////////////////////////////////////////////////////////////////////// + +template <typename NestedT = non_nested_refactoring> +class attach_action_gen; + +template <typename ActionT, typename NestedT = non_nested_refactoring> +class attach_action_parser : + public parser<attach_action_parser<ActionT, NestedT> > { + +public: + // the parser to refactor has to be at least a action_parser_category + // parser + BOOST_STATIC_ASSERT(( + boost::is_convertible<typename ActionT::parser_category_t, + action_parser_category>::value + )); + + attach_action_parser(ActionT const& actor_, NestedT const& nested_) + : actor(actor_), nested(nested_) {} + + typedef attach_action_parser<ActionT, NestedT> self_t; + typedef attach_action_gen<NestedT> parser_generator_t; + typedef typename ActionT::parser_category_t parser_category_t; + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + return impl::attach_action_type<NestedT>:: + parse(*this, scan, actor, nested); + } + +private: + typename as_parser<ActionT>::type::embed_t actor; + typename NestedT::embed_t nested; +}; + +////////////////////////////////// +template <typename NestedT> +class attach_action_gen { + +public: + typedef attach_action_gen<NestedT> embed_t; + + attach_action_gen(NestedT const& nested_ = non_nested_refactoring()) + : nested(nested_) {} + + template <typename ParserT, typename ActionT> + attach_action_parser<action<ParserT, ActionT>, NestedT> + operator[](action<ParserT, ActionT> const& actor) const + { + return attach_action_parser<action<ParserT, ActionT>, NestedT> + (actor, nested); + } + +private: + typename NestedT::embed_t nested; +}; + +const attach_action_gen<> attach_action_d = attach_action_gen<>(); + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(pop) +#endif + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif // BOOST_SPIRIT_REFACTORING_HPP + diff --git a/boost/spirit/home/classic/meta/traverse.hpp b/boost/spirit/home/classic/meta/traverse.hpp new file mode 100644 index 0000000000..aef68cb7e9 --- /dev/null +++ b/boost/spirit/home/classic/meta/traverse.hpp @@ -0,0 +1,222 @@ +/*============================================================================= + Copyright (c) 2002-2003 Joel de Guzman + Copyright (c) 2002-2003 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_TRAVERSE_HPP) +#define BOOST_SPIRIT_TRAVERSE_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/meta/impl/traverse.ipp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // Post-order traversal of auxilliary parsers. + // + /////////////////////////////////////////////////////////////////////////// + struct post_order + { + // Return the parser type, which is generated as the result of the + // traverse function below. + + template <typename MetaT, typename ParserT> + struct result + { + typedef typename + traverse_post_order_return< + MetaT + , ParserT + , traverse_post_order_env<0, 0, 0, 0> + >::type + type; + }; + + // Traverse a given parser and refactor it with the help of the given + // MetaT metafunction template. + + template <typename MetaT, typename ParserT> + static typename result<MetaT, ParserT>::type + traverse(MetaT const &meta_, ParserT const &parser_) + { + typedef typename ParserT::parser_category_t parser_category_t; + return impl::traverse_post_order<parser_category_t>::generate( + meta_, parser_, traverse_post_order_env<0, 0, 0, 0>()); + } + }; + + /////////////////////////////////////////////////////////////////////////// + // + // Transform policies + // + // The following policy classes could be used to assemble some new + // transformation metafunction which uses identity transformations + // for some parser_category type parsers. + // + /////////////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////////////// + // transform plain parsers + template <typename TransformT> + struct plain_identity_policy + { + template <typename ParserT, typename EnvT> + struct plain_result + { + // plain parsers should be embedded and returned correctly + typedef typename ParserT::embed_t type; + }; + + template <typename ParserT, typename EnvT> + typename parser_traversal_plain_result<TransformT, ParserT, EnvT>::type + generate_plain(ParserT const &parser_, EnvT const& /*env*/) const + { + return parser_; + } + }; + + ////////////////////////////////// + // transform unary parsers + template <typename UnaryT, typename SubjectT> + struct unary_identity_policy_return + { + typedef typename UnaryT::parser_generator_t parser_generator_t; + typedef typename parser_generator_t + ::template result<SubjectT>::type type; + }; + + template <typename TransformT> + struct unary_identity_policy + { + template <typename UnaryT, typename SubjectT, typename EnvT> + struct unary_result + { + typedef + typename unary_identity_policy_return<UnaryT, SubjectT>::type + type; + }; + + template <typename UnaryT, typename SubjectT, typename EnvT> + typename parser_traversal_unary_result< + TransformT, UnaryT, SubjectT, EnvT>::type + generate_unary( + UnaryT const &, SubjectT const &subject_, EnvT const& /*env*/) const + { + typedef typename UnaryT::parser_generator_t parser_generator_t; + return parser_generator_t::template generate<SubjectT>(subject_); + } + }; + + ////////////////////////////////// + // transform action parsers + template <typename TransformT> + struct action_identity_policy + { + template <typename ActionT, typename SubjectT, typename EnvT> + struct action_result + { + typedef action<SubjectT, typename ActionT::predicate_t> type; + }; + + template <typename ActionT, typename SubjectT, typename EnvT> + typename parser_traversal_action_result< + TransformT, ActionT, SubjectT, EnvT + >::type + generate_action(ActionT const &action_, SubjectT const &subject_, + EnvT const& /*env*/) const + { + return subject_[action_.predicate()]; + } + }; + + ////////////////////////////////// + // transform binary parsers + template <typename BinaryT, typename LeftT, typename RightT> + struct binary_identity_policy_return + { + typedef typename BinaryT::parser_generator_t parser_generator_t; + typedef typename parser_generator_t + ::template result<LeftT, RightT>::type type; + }; + + template <typename TransformT> + struct binary_identity_policy + { + template <typename BinaryT, typename LeftT + , typename RightT, typename EnvT> + struct binary_result { + + typedef typename + binary_identity_policy_return<BinaryT, LeftT, RightT>::type + type; + }; + + template <typename BinaryT, typename LeftT + , typename RightT, typename EnvT> + typename parser_traversal_binary_result< + TransformT, BinaryT, LeftT, RightT, EnvT + >::type + generate_binary( + BinaryT const &, LeftT const& left_ + , RightT const& right_, EnvT const& /*env*/) const + { + typedef typename BinaryT::parser_generator_t parser_generator_t; + return parser_generator_t:: + template generate<LeftT, RightT>(left_, right_); + } + }; + + /////////////////////////////////////////////////////////////////////////// + // + // transform_policies template + // + // The transform_policies template metafunction could serve as a + // base class for new metafunctions to be passed to the traverse meta + // template (see above), where only minimal parts have to be + // overwritten. + // + /////////////////////////////////////////////////////////////////////////// + + template < + typename TransformT, + typename PlainPolicyT = plain_identity_policy<TransformT>, + typename UnaryPolicyT = unary_identity_policy<TransformT>, + typename ActionPolicyT = action_identity_policy<TransformT>, + typename BinaryPolicyT = binary_identity_policy<TransformT> + > + struct transform_policies : + public PlainPolicyT, + public UnaryPolicyT, + public ActionPolicyT, + public BinaryPolicyT + { + }; + + /////////////////////////////////////////////////////////////////////////// + // + // Identity transformation + // + // The identity_transform metafunction supplied to the traverse + // template will generate a new parser, which will be exactly + // identical to the parser given as the parameter to the traverse + // metafunction. I.e. the following conceptual 'equation' will be + // always true: + // + // some_parser == + // post_order::traverse(identity_transform(), some_parser) + // + /////////////////////////////////////////////////////////////////////////// + + struct identity_transform : transform_policies<identity_transform> {}; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif // !defined(BOOST_SPIRIT_TRAVERSE_HPP) diff --git a/boost/spirit/home/classic/namespace.hpp b/boost/spirit/home/classic/namespace.hpp new file mode 100644 index 0000000000..f64fc81bb6 --- /dev/null +++ b/boost/spirit/home/classic/namespace.hpp @@ -0,0 +1,35 @@ +/*============================================================================= + Copyright (c) 2001-2008 Joel de Guzman + Copyright (c) 2001-2008 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(SPIRIT_CLASSIC_NAMESPACE_HPP) +#define SPIRIT_CLASSIC_NAMESPACE_HPP + +#if defined(BOOST_SPIRIT_USE_OLD_NAMESPACE) + +// Use the old namespace for Spirit.Classic, everything is located in the +// namespace boost::spirit. +// This is in place for backwards compatibility with Spirit V1.8.x. Don't use +// it when combining Spirit.Classic with other parts of the library + +#define BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN /*namespace classic {*/ +#define BOOST_SPIRIT_CLASSIC_NS boost::spirit/*::classic*/ +#define BOOST_SPIRIT_CLASSIC_NAMESPACE_END /*}*/ + +#else + +// This is the normal (and suggested) mode of operation when using +// Spirit.Classic. Everything will be located in the namespace +// boost::spirit::classic, avoiding name clashes with other parts of Spirit. + +#define BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN namespace classic { +#define BOOST_SPIRIT_CLASSIC_NS boost::spirit::classic +#define BOOST_SPIRIT_CLASSIC_NAMESPACE_END } + +#endif + +#endif diff --git a/boost/spirit/home/classic/phoenix.hpp b/boost/spirit/home/classic/phoenix.hpp new file mode 100644 index 0000000000..c0aadd1743 --- /dev/null +++ b/boost/spirit/home/classic/phoenix.hpp @@ -0,0 +1,25 @@ +/*============================================================================= + Phoenix V1.2.1 + Copyright (c) 2001-2002 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_PHOENIX_HPP) +#define BOOST_SPIRIT_PHOENIX_HPP + +#include <boost/spirit/home/classic/phoenix/tuples.hpp> +#include <boost/spirit/home/classic/phoenix/tuple_helpers.hpp> +#include <boost/spirit/home/classic/phoenix/actor.hpp> +#include <boost/spirit/home/classic/phoenix/primitives.hpp> +#include <boost/spirit/home/classic/phoenix/composite.hpp> +#include <boost/spirit/home/classic/phoenix/functions.hpp> +#include <boost/spirit/home/classic/phoenix/operators.hpp> +#include <boost/spirit/home/classic/phoenix/special_ops.hpp> +#include <boost/spirit/home/classic/phoenix/statements.hpp> +#include <boost/spirit/home/classic/phoenix/binders.hpp> +#include <boost/spirit/home/classic/phoenix/closures.hpp> +#include <boost/spirit/home/classic/phoenix/casts.hpp> +#include <boost/spirit/home/classic/phoenix/new.hpp> + +#endif // !defined(BOOST_SPIRIT_PHOENIX_HPP) diff --git a/boost/spirit/home/classic/phoenix/actor.hpp b/boost/spirit/home/classic/phoenix/actor.hpp new file mode 100644 index 0000000000..67a4b02898 --- /dev/null +++ b/boost/spirit/home/classic/phoenix/actor.hpp @@ -0,0 +1,604 @@ +/*============================================================================= + Phoenix v1.2 + Copyright (c) 2001-2002 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) +==============================================================================*/ +#ifndef PHOENIX_ACTOR_HPP +#define PHOENIX_ACTOR_HPP + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/spirit/home/classic/phoenix/tuples.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace phoenix { + +// These are forward declared here because we cannot include impl.hpp +// or operators.hpp yet but the actor's assignment operator and index +// operator are required to be members. + +////////////////////////////////// +struct assign_op; +struct index_op; + +////////////////////////////////// +namespace impl { + + template <typename OperationT, typename BaseT, typename B> + struct make_binary1; +} + +/////////////////////////////////////////////////////////////////////////////// +// +// unpack_tuple class +// +// This class is used to unpack a supplied tuple such, that the members of +// this tuple will be handled as if they would be supplied separately. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename TupleT> +struct unpack_tuple : public TupleT { + + typedef TupleT tuple_t; + + unpack_tuple() {} + unpack_tuple(tuple_t const &tuple_) : TupleT(tuple_) {} +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// actor class +// +// This class is a protocol class for all actors. This class is +// essentially an interface contract. The actor class does not +// really know how how to act on anything but instead relies on the +// template parameter BaseT (from which the actor will derive from) +// to do the actual action. +// +// An actor is a functor that is capable of accepting arguments up +// to a predefined maximum. It is up to the base class to do the +// actual processing or possibly to limit the arity (no. of +// arguments) passed in. Upon invocation of the functor through a +// supplied operator(), the actor funnels the arguments passed in +// by the client into a tuple and calls the base eval member +// function. +// +// Schematically: +// +// arg0 ---------| +// arg1 ---------| +// arg2 ---------|---> tupled_args ---> base.eval +// ... | +// argN ---------| +// +// actor::operator()(arg0, arg1... argN) +// ---> BaseT::eval(tupled_args); +// +// Actor base classes from which this class inherits from are +// expected to have a corresponding member function eval compatible +// with the conceptual Interface: +// +// template <typename TupleT> +// actor_return_type +// eval(TupleT const& args) const; +// +// where args are the actual arguments passed in by the client +// funneled into a tuple (see tuple.hpp for details). +// +// The actor_return_type can be anything. Base classes are free to +// return any type, even argument dependent types (types that are +// deduced from the types of the arguments). After evaluating the +// parameters and doing some computations or actions, the eval +// member function concludes by returning something back to the +// client. To do this, the forwarding function (the actor's +// operator()) needs to know the return type of the eval member +// function that it is calling. For this purpose, actor base +// classes are required to provide a nested template class: +// +// template <typename TupleT> +// struct result; +// +// This auxiliary class provides the result type information +// returned by the eval member function of a base actor class. The +// nested template class result should have a typedef 'type' that +// reflects the return type of its member function eval. It is +// basically a type computer that answers the question "given +// arguments packed into a TupleT type, what will be the result +// type of the eval member function of ActorT?". The template class +// actor_result queries this to extract the return type of an +// actor. Example: +// +// typedef typename actor_result<ActorT, TupleT>::type +// actor_return_type; +// +// where actor_return_type is the actual type returned by ActorT's +// eval member function given some arguments in a TupleT. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename ActorT, typename TupleT> +struct actor_result { + + typedef typename ActorT::template result<TupleT>::type type; + typedef typename remove_reference<type>::type plain_type; +}; + +////////////////////////////////// +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(push) +#pragma warning(disable:4512) //assignment operator could not be generated +#endif + +template <typename BaseT> +struct actor : public BaseT { + + actor(); + actor(BaseT const& base); + + typename actor_result<BaseT, tuple<> >::type + operator()() const; + + template <typename A> + typename actor_result<BaseT, tuple<A&> >::type + operator()(A& a) const; + + template <typename A, typename B> + typename actor_result<BaseT, tuple<A&, B&> >::type + operator()(A& a, B& b) const; + + template <typename A, typename B, typename C> + typename actor_result<BaseT, tuple<A&, B&, C&> >::type + operator()(A& a, B& b, C& c) const; + +#if PHOENIX_LIMIT > 3 + template <typename A, typename B, typename C, typename D> + typename actor_result<BaseT, tuple<A&, B&, C&, D&> >::type + operator()(A& a, B& b, C& c, D& d) const; + + template <typename A, typename B, typename C, typename D, typename E> + typename actor_result<BaseT, tuple<A&, B&, C&, D&, E&> >::type + operator()(A& a, B& b, C& c, D& d, E& e) const; + + template < + typename A, typename B, typename C, typename D, typename E, + typename F> + typename actor_result<BaseT, tuple<A&, B&, C&, D&, E&, F&> >::type + operator()(A& a, B& b, C& c, D& d, E& e, F& f) const; + +#if PHOENIX_LIMIT > 6 + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G> + typename actor_result<BaseT, tuple<A&, B&, C&, D&, E&, F&, G&> >::type + operator()(A& a, B& b, C& c, D& d, E& e, F& f, G& g) const; + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H> + typename actor_result<BaseT, + tuple<A&, B&, C&, D&, E&, F&, G&, H&> + >::type + operator()(A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h) const; + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I> + typename actor_result<BaseT, + tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&> + >::type + operator()(A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i) const; + +#if PHOENIX_LIMIT > 9 + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J> + typename actor_result<BaseT, + tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&> + >::type + operator()( + A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j) const; + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K> + typename actor_result<BaseT, + tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&> + >::type + operator()( + A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j, + K& k) const; + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L> + typename actor_result<BaseT, + tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&> + >::type + operator()( + A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j, + K& k, L& l) const; + +#if PHOENIX_LIMIT > 12 + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M> + typename actor_result<BaseT, + tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&> + >::type + operator()( + A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j, + K& k, L& l, M& m) const; + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M, typename N> + typename actor_result<BaseT, + tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&> + >::type + operator()( + A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j, + K& k, L& l, M& m, N& n) const; + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M, typename N, typename O> + typename actor_result<BaseT, + tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&, O&> + >::type + operator()( + A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j, + K& k, L& l, M& m, N& n, O& o) const; + +#endif +#endif +#endif +#endif + + template <typename TupleT> + typename actor_result<BaseT, unpack_tuple<TupleT> >::type + operator()(unpack_tuple<TupleT> const &t) const; + + template <typename B> + typename impl::make_binary1<assign_op, BaseT, B>::type + operator=(B const& b) const; + + template <typename B> + typename impl::make_binary1<index_op, BaseT, B>::type + operator[](B const& b) const; +}; + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(pop) +#endif + +/////////////////////////////////////////////////////////////////////////// +// +// as_actor +// +// as_actor is a meta-program that converts an arbitrary type into +// an actor. All participants in the framework must be first-class +// actors. This meta-program is used all throughout the framework +// whenever an unknown type needs to be converted to an actor. +// as_actor specializations are expected to have a typedef 'type'. +// This is the destination actor type. A static member function +// 'convert' converts an object to this target type. +// +// The meta-program does no conversion if the object to be +// converted is already an actor. +// +/////////////////////////////////////////////////////////////////////////// +template <typename T> +struct as_actor; + +////////////////////////////////// +template <typename BaseT> +struct as_actor<actor<BaseT> > { + + typedef actor<BaseT> type; + static type convert(actor<BaseT> const& x) { return x; } +}; + +////////////////////////////////// +template <> +struct as_actor<nil_t> { + + typedef nil_t type; + static nil_t convert(nil_t /*x*/) + { return nil_t(); } +}; + +////////////////////////////////// +template <> +struct as_actor<void> { + + typedef void type; + // ERROR!!! +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// actor class implementation +// +/////////////////////////////////////////////////////////////////////////////// +template <typename BaseT> +actor<BaseT>::actor() +: BaseT() {} + +////////////////////////////////// +template <typename BaseT> +actor<BaseT>::actor(BaseT const& base) +: BaseT(base) {} + +////////////////////////////////// +template <typename BaseT> +inline typename actor_result<BaseT, tuple<> >::type +actor<BaseT>::operator()() const +{ + return BaseT::eval(tuple<>()); +} + +////////////////////////////////// +template <typename BaseT> +template <typename A> +inline typename actor_result<BaseT, tuple<A&> >::type +actor<BaseT>::operator()(A& a_) const +{ + return BaseT::eval(tuple<A&>(a_)); +} + +////////////////////////////////// +template <typename BaseT> +template <typename A, typename B> +inline typename actor_result<BaseT, tuple<A&, B&> >::type +actor<BaseT>::operator()(A& a_, B& b_) const +{ + return BaseT::eval(tuple<A&, B&>(a_, b_)); +} + +////////////////////////////////// +template <typename BaseT> +template <typename A, typename B, typename C> +inline typename actor_result<BaseT, tuple<A&, B&, C&> >::type +actor<BaseT>::operator()(A& a_, B& b_, C& c_) const +{ + return BaseT::eval(tuple<A&, B&, C&>(a_, b_, c_)); +} + +#if PHOENIX_LIMIT > 3 +////////////////////////////////// +template <typename BaseT> +template <typename A, typename B, typename C, typename D> +inline typename actor_result<BaseT, tuple<A&, B&, C&, D&> >::type +actor<BaseT>::operator()(A& a_, B& b_, C& c_, D& d_) const +{ + return BaseT::eval(tuple<A&, B&, C&, D&>(a_, b_, c_, d_)); +} + +////////////////////////////////// +template <typename BaseT> +template <typename A, typename B, typename C, typename D, typename E> +inline typename actor_result<BaseT, tuple<A&, B&, C&, D&, E&> >::type +actor<BaseT>::operator()(A& a_, B& b_, C& c_, D& d_, E& e_) const +{ + return BaseT::eval(tuple<A&, B&, C&, D&, E&>(a_, b_, c_, d_, e_)); +} + +////////////////////////////////// +template <typename BaseT> +template < + typename A, typename B, typename C, typename D, typename E, + typename F> +inline typename actor_result<BaseT, + tuple<A&, B&, C&, D&, E&, F&> +>::type +actor<BaseT>::operator()( + A& a_, B& b_, C& c_, D& d_, E& e_, F& f_ +) const +{ + return BaseT::eval( + tuple<A&, B&, C&, D&, E&, F&> + (a_, b_, c_, d_, e_, f_) + ); +} + +#if PHOENIX_LIMIT > 6 +////////////////////////////////// +template <typename BaseT> +template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G> +inline typename actor_result<BaseT, + tuple<A&, B&, C&, D&, E&, F&, G&> +>::type +actor<BaseT>::operator()( + A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_ +) const +{ + return BaseT::eval( + tuple<A&, B&, C&, D&, E&, F&, G&> + (a_, b_, c_, d_, e_, f_, g_) + ); +} + +////////////////////////////////// +template <typename BaseT> +template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H> +inline typename actor_result<BaseT, + tuple<A&, B&, C&, D&, E&, F&, G&, H&> +>::type +actor<BaseT>::operator()( + A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_ +) const +{ + return BaseT::eval( + tuple<A&, B&, C&, D&, E&, F&, G&, H&> + (a_, b_, c_, d_, e_, f_, g_, h_) + ); +} + +////////////////////////////////// +template <typename BaseT> +template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I> +inline typename actor_result<BaseT, + tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&> +>::type +actor<BaseT>::operator()( + A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_ +) const +{ + return BaseT::eval( + tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&> + (a_, b_, c_, d_, e_, f_, g_, h_, i_) + ); +} + +#if PHOENIX_LIMIT > 9 +////////////////////////////////// +template <typename BaseT> +template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J> +inline typename actor_result<BaseT, + tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&> +>::type +actor<BaseT>::operator()( + A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_, J& j_ +) const +{ + return BaseT::eval( + tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&> + (a_, b_, c_, d_, e_, f_, g_, h_, i_, j_) + ); +} + +////////////////////////////////// +template <typename BaseT> +template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K> +inline typename actor_result<BaseT, + tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&> +>::type +actor<BaseT>::operator()( + A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_, J& j_, + K& k_ +) const +{ + return BaseT::eval( + tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&> + (a_, b_, c_, d_, e_, f_, g_, h_, i_, j_, k_) + ); +} + +////////////////////////////////// +template <typename BaseT> +template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L> +inline typename actor_result<BaseT, + tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&> +>::type +actor<BaseT>::operator()( + A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_, J& j_, + K& k_, L& l_ +) const +{ + return BaseT::eval( + tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&> + (a_, b_, c_, d_, e_, f_, g_, h_, i_, j_, k_, l_) + ); +} + +#if PHOENIX_LIMIT > 12 +////////////////////////////////// +template <typename BaseT> +template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M> +inline typename actor_result<BaseT, + tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&> +>::type +actor<BaseT>::operator()( + A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_, J& j_, + K& k_, L& l_, M& m_ +) const +{ + return BaseT::eval( + tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&> + (a_, b_, c_, d_, e_, f_, g_, h_, i_, j_, k_, l_, m_) + ); +} + +////////////////////////////////// +template <typename BaseT> +template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M, typename N> +inline typename actor_result<BaseT, + tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&> +>::type +actor<BaseT>::operator()( + A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_, J& j_, + K& k_, L& l_, M& m_, N& n_ +) const +{ + return BaseT::eval( + tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&> + (a_, b_, c_, d_, e_, f_, g_, h_, i_, j_, k_, l_, m_, n_) + ); +} + +////////////////////////////////// +template <typename BaseT> +template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M, typename N, typename O> +inline typename actor_result<BaseT, + tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&, O&> +>::type +actor<BaseT>::operator()( + A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_, J& j_, + K& k_, L& l_, M& m_, N& n_, O& o_ +) const +{ + return BaseT::eval( + tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&, O&> + (a_, b_, c_, d_, e_, f_, g_, h_, i_, j_, k_, l_, m_, n_, o_) + ); +} + +#endif +#endif +#endif +#endif + +////////////////////////////////// +template <typename BaseT> +template <typename TupleT> +typename actor_result<BaseT, unpack_tuple<TupleT> >::type +actor<BaseT>::operator()(unpack_tuple<TupleT> const &t) const +{ + return BaseT::eval(t); +} + +/////////////////////////////////////////////////////////////////////////////// +} // namespace phoenix + +#endif diff --git a/boost/spirit/home/classic/phoenix/binders.hpp b/boost/spirit/home/classic/phoenix/binders.hpp new file mode 100644 index 0000000000..a1d115903e --- /dev/null +++ b/boost/spirit/home/classic/phoenix/binders.hpp @@ -0,0 +1,4066 @@ +/*============================================================================= + Phoenix v1.2 + Copyright (c) 2001-2002 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) +==============================================================================*/ +#ifndef PHOENIX_BINDERS_HPP +#define PHOENIX_BINDERS_HPP + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/spirit/home/classic/phoenix/functions.hpp> +#include <boost/type_traits/is_const.hpp> +#include <boost/mpl/if.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace phoenix { + +/////////////////////////////////////////////////////////////////////////////// +// +// Binders +// +// There are times when it is desireable to bind a simple functor, +// function, member function or member variable for deferred +// evaluation. This can be done through the binding facilities +// provided below. There are template classes: +// +// 1) function_ptr ( function pointer binder ) +// 2) functor ( functor pointer binder ) +// 3) member_function_ptr ( member function pointer binder ) +// 4) member_var_ptr ( member variable pointer binder ) +// +// These template classes are specialized lazy function classes for +// functors, function pointers, member function pointers and member +// variable pointers, respectively. These are subclasses of the +// lazy-function class (see functions.hpp). Each of these has a +// corresponding overloaded bind(x) function. Each bind(x) function +// generates a suitable binder object. +// +// Example, given a function foo: +// +// void foo_(int n) { std::cout << n << std::endl; } +// +// Here's how the function foo is bound: +// +// bind(&foo_) +// +// This bind expression results to a lazy-function (see +// functions.hpp) that is lazily evaluated. This bind expression is +// also equivalent to: +// +// function_ptr<void, int> foo = &foo_; +// +// The template parameter of the function_ptr is the return and +// argument types of actual signature of the function to be bound +// read from left to right: +// +// void foo_(int); ---> function_ptr<void, int> +// +// Either bind(&foo_) and its equivalent foo can now be used in the +// same way a lazy function (see functions.hpp) is used: +// +// bind(&foo_)(arg1) +// +// or +// +// foo(arg1) +// +// The latter, of course, being much easier to understand. This is +// now a full-fledged lazy function that can finally be evaluated +// by another function call invocation. A second function call will +// invoke the actual foo function: +// +// int i = 4; +// foo(arg1)(i); +// +// will print out "4". +// +// Binding functors and member functions can be done similarly. +// Here's how to bind a functor (e.g. std::plus<int>): +// +// bind(std::plus<int>()) +// +// or +// +// functor<std::plus<int> > plus; +// +// Again, these are full-fledged lazy functions. In this case, +// unlike the first example, expect 2 arguments (std::plus<int> +// needs two arguments lhs and rhs). Either or both of which can be +// lazily bound: +// +// plus(arg1, arg2) // arg1 + arg2 +// plus(100, arg1) // 100 + arg1 +// plus(100, 200) // 300 +// +// A bound member function takes in a pointer or reference to an +// object as the first argument. For instance, given: +// +// struct xyz { void foo(int) const; }; +// +// xyz's foo member function can be bound as: +// +// bind(&xyz::foo) +// +// or +// +// member_function_ptr<void, xyz, int> xyz_foo = &xyz::foo; +// +// The template parameter of the member_function_ptr is the return, +// class and argument types of actual signature of the function to +// be bound read from left to right: +// +// void xyz::foo_(int); ---> member_function_ptr<void, xyz, int> +// +// Take note that a member_function_ptr lazy-function expects the +// first argument to be a pointer or reference to an object. Both +// the object (reference or pointer) and the arguments can be +// lazily bound. Examples: +// +// xyz obj; +// xyz_foo(arg1, arg2) // arg1.foo(arg2) +// xyz_foo(obj, arg1) // obj.foo(arg1) +// xyz_foo(obj, 100) // obj.foo(100) +// +// Be reminded that var(obj) must be used to call non-const member +// functions. For example, if xyz was declared as: +// +// struct xyz { void foo(int); }; +// +// the pointer or reference to the object must also be non-const. +// Lazily bound arguments are stored as const value by default (see +// variable class in primitives.hpp). +// +// xyz_foo(var(obj), 100) // obj.foo(100) +// +// Finally, member variables can be bound much like member +// functions. For instance, given: +// +// struct xyz { int v; }; +// +// xyz::v can be bound as: +// +// bind(&xyz::v) +// or +// +// member_var_ptr<int, xyz> xyz_v = &xyz::v; +// +// The template parameter of the member_var_ptr is the type of the +// variable followed by the class: +// +// int xyz::v; ---> member_var_ptr<int, xyz> +// +// Just like the member_function_ptr, member_var_ptr also expects +// the first argument to be a pointer or reference to an object. +// Both the object (reference or pointer) and the arguments can be +// lazily bound. Examples: +// +// xyz obj; +// xyz_v(arg1) // arg1.v +// xyz_v(obj) // obj.v +// +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// +// Functor binder +// +/////////////////////////////////////////////////////////////////////////////// +template <typename FuncT> +struct functor_action : public FuncT { + +#if !defined(__BORLANDC__) && (!defined(__MWERKS__) || (__MWERKS__ > 0x3002)) + + template < + typename A = nil_t + , typename B = nil_t + , typename C = nil_t + +#if PHOENIX_LIMIT > 3 + , typename D = nil_t + , typename E = nil_t + , typename F = nil_t + +#if PHOENIX_LIMIT > 6 + , typename G = nil_t + , typename H = nil_t + , typename I = nil_t + +#if PHOENIX_LIMIT > 9 + , typename J = nil_t + , typename K = nil_t + , typename L = nil_t + +#if PHOENIX_LIMIT > 12 + , typename M = nil_t + , typename N = nil_t + , typename O = nil_t + +#endif +#endif +#endif +#endif + > + struct result { typedef typename FuncT::result_type type; }; +#endif + + functor_action(FuncT fptr_ = FuncT()) + : FuncT(fptr_) {} +}; + +#if defined(__BORLANDC__) || (defined(__MWERKS__) && (__MWERKS__ <= 0x3002)) + +/////////////////////////////////////////////////////////////////////////////// +// +// The following specializations are needed because Borland and CodeWarrior +// does not accept default template arguments in nested template classes in +// classes (i.e functor_action::result) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename FuncT, typename TupleT> +struct composite0_result<functor_action<FuncT>, TupleT> { + + typedef typename FuncT::result_type type; +}; + +////////////////////////////////// +template <typename FuncT, typename TupleT, + typename A> +struct composite1_result<functor_action<FuncT>, TupleT, A> { + + typedef typename FuncT::result_type type; +}; + +////////////////////////////////// +template <typename FuncT, typename TupleT, + typename A, typename B> +struct composite2_result<functor_action<FuncT>, TupleT, A, B> { + + typedef typename FuncT::result_type type; +}; + +////////////////////////////////// +template <typename FuncT, typename TupleT, + typename A, typename B, typename C> +struct composite3_result<functor_action<FuncT>, TupleT, A, B, C> { + + typedef typename FuncT::result_type type; +}; + +#if PHOENIX_LIMIT > 3 +////////////////////////////////// +template <typename FuncT, typename TupleT, + typename A, typename B, typename C, typename D> +struct composite4_result<functor_action<FuncT>, TupleT, + A, B, C, D> { + + typedef typename FuncT::result_type type; +}; + +////////////////////////////////// +template <typename FuncT, typename TupleT, + typename A, typename B, typename C, typename D, typename E> +struct composite5_result<functor_action<FuncT>, TupleT, + A, B, C, D, E> { + + typedef typename FuncT::result_type type; +}; + +////////////////////////////////// +template <typename FuncT, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F> +struct composite6_result<functor_action<FuncT>, TupleT, + A, B, C, D, E, F> { + + typedef typename FuncT::result_type type; +}; + +#if PHOENIX_LIMIT > 6 +////////////////////////////////// +template <typename FuncT, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G> +struct composite7_result<functor_action<FuncT>, TupleT, + A, B, C, D, E, F, G> { + + typedef typename FuncT::result_type type; +}; + +////////////////////////////////// +template <typename FuncT, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H> +struct composite8_result<functor_action<FuncT>, TupleT, + A, B, C, D, E, F, G, H> { + + typedef typename FuncT::result_type type; +}; + +////////////////////////////////// +template <typename FuncT, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I> +struct composite9_result<functor_action<FuncT>, TupleT, + A, B, C, D, E, F, G, H, I> { + + typedef typename FuncT::result_type type; +}; + +#if PHOENIX_LIMIT > 9 +////////////////////////////////// +template <typename FuncT, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J> +struct composite10_result<functor_action<FuncT>, TupleT, + A, B, C, D, E, F, G, H, I, J> { + + typedef typename FuncT::result_type type; +}; + +////////////////////////////////// +template <typename FuncT, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K> +struct composite11_result<functor_action<FuncT>, TupleT, + A, B, C, D, E, F, G, H, I, J, K> { + + typedef typename FuncT::result_type type; +}; + +////////////////////////////////// +template <typename FuncT, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L> +struct composite12_result<functor_action<FuncT>, TupleT, + A, B, C, D, E, F, G, H, I, J, K, L> { + + typedef typename FuncT::result_type type; +}; + +#if PHOENIX_LIMIT > 12 +////////////////////////////////// +template <typename FuncT, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M> +struct composite13_result<functor_action<FuncT>, TupleT, + A, B, C, D, E, F, G, H, I, J, K, L, M> { + + typedef typename FuncT::result_type type; +}; + +////////////////////////////////// +template <typename FuncT, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M, typename N> +struct composite14_result<functor_action<FuncT>, TupleT, + A, B, C, D, E, F, G, H, I, J, K, L, M, N> { + + typedef typename FuncT::result_type type; +}; + +////////////////////////////////// +template <typename FuncT, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M, typename N, typename O> +struct composite15_result<functor_action<FuncT>, TupleT, + A, B, C, D, E, F, G, H, I, J, K, L, M, N, O> { + + typedef typename FuncT::result_type type; +}; + +#endif +#endif +#endif +#endif +#endif + +////////////////////////////////// +template <typename FuncT> +struct functor : public function<functor_action<FuncT> > { + + functor(FuncT func) + : function<functor_action<FuncT> >(functor_action<FuncT>(func)) {}; +}; + +////////////////////////////////// +template <typename FuncT> +inline functor<FuncT> +bind(FuncT func) +{ + return functor<FuncT>(func); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Member variable pointer binder +// +/////////////////////////////////////////////////////////////////////////////// +namespace impl { + + ////////////////////////////////// + template <typename T> + struct as_ptr { + + typedef T* pointer_type; + + static T* get(T& ref) + { return &ref; } + }; + + ////////////////////////////////// + template <typename T> + struct as_ptr<T*> { + + typedef T* pointer_type; + + static T* get(T* ptr) + { return ptr; } + }; +} + +////////////////////////////////// +template <typename ActionT, typename ClassT> +struct member_var_ptr_action_result { + + typedef typename ActionT::template result<ClassT>::type type; +}; + +////////////////////////////////// +template <typename T, typename ClassT> +struct member_var_ptr_action { + + typedef member_var_ptr_action<T, ClassT> self_t; + + template <typename CT> + struct result { + typedef typename boost::mpl::if_<boost::is_const<CT>, T const&, T& + >::type type; + }; + + typedef T ClassT::*mem_var_ptr_t; + + member_var_ptr_action(mem_var_ptr_t ptr_) + : ptr(ptr_) {} + + template <typename CT> + typename member_var_ptr_action_result<self_t, CT>::type + operator()(CT& obj) const + { return impl::as_ptr<CT>::get(obj)->*ptr; } + + mem_var_ptr_t ptr; +}; + +////////////////////////////////// +template <typename T, typename ClassT> +struct member_var_ptr +: public function<member_var_ptr_action<T, ClassT> > { + + member_var_ptr(T ClassT::*mp) + : function<member_var_ptr_action<T, ClassT> > + (member_var_ptr_action<T, ClassT>(mp)) {} +}; + +////////////////////////////////// +template <typename T, typename ClassT> +inline member_var_ptr<T, ClassT> +bind(T ClassT::*mp) +{ + return member_var_ptr<T, ClassT>(mp); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Function pointer binder (main class) +// +/////////////////////////////////////////////////////////////////////////////// +template < + typename RT + , typename A = nil_t + , typename B = nil_t + , typename C = nil_t + +#if PHOENIX_LIMIT > 3 + , typename D = nil_t + , typename E = nil_t + , typename F = nil_t + +#if PHOENIX_LIMIT > 6 + , typename G = nil_t + , typename H = nil_t + , typename I = nil_t + +#if PHOENIX_LIMIT > 9 + , typename J = nil_t + , typename K = nil_t + , typename L = nil_t + +#if PHOENIX_LIMIT > 12 + , typename M = nil_t + , typename N = nil_t + , typename O = nil_t + +#endif +#endif +#endif +#endif + + , typename NU = nil_t // Not used +> +struct function_ptr_action; + +////////////////////////////////// +template < + typename RT + , typename A = nil_t + , typename B = nil_t + , typename C = nil_t + +#if PHOENIX_LIMIT > 3 + , typename D = nil_t + , typename E = nil_t + , typename F = nil_t + +#if PHOENIX_LIMIT > 6 + , typename G = nil_t + , typename H = nil_t + , typename I = nil_t + +#if PHOENIX_LIMIT > 9 + , typename J = nil_t + , typename K = nil_t + , typename L = nil_t + +#if PHOENIX_LIMIT > 12 + , typename M = nil_t + , typename N = nil_t + , typename O = nil_t + +#endif +#endif +#endif +#endif +> +struct function_ptr +: public function<function_ptr_action<RT + , A, B, C +#if PHOENIX_LIMIT > 3 + , D, E, F +#if PHOENIX_LIMIT > 6 + , G, H, I +#if PHOENIX_LIMIT > 9 + , J, K, L +#if PHOENIX_LIMIT > 12 + , M, N, O +#endif +#endif +#endif +#endif + > > { + + typedef function_ptr_action<RT + , A, B, C +#if PHOENIX_LIMIT > 3 + , D, E, F +#if PHOENIX_LIMIT > 6 + , G, H, I +#if PHOENIX_LIMIT > 9 + , J, K, L +#if PHOENIX_LIMIT > 12 + , M, N, O +#endif +#endif +#endif +#endif + > action_t; + + template <typename FPT> + function_ptr(FPT fp) + : function<action_t>(action_t(fp)) {} +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// Function pointer binder (specialization for 0 arg) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT> +struct function_ptr_action<RT, + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 3 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 6 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif +#endif +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(*func_ptr_t)(); + + function_ptr_action(func_ptr_t fptr_) + : fptr(fptr_) {} + + result_type operator()() const + { return fptr(); } + + func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT> +inline function_ptr<RT> +bind(RT(*fptr)()) +{ + return function_ptr<RT>(fptr); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Function pointer binder (specialization for 1 arg) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, typename A> +struct function_ptr_action<RT, + A, nil_t, nil_t, +#if PHOENIX_LIMIT > 3 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 6 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif +#endif +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(*func_ptr_t)(A); + + template <typename A_> + struct result { typedef result_type type; }; + + function_ptr_action(func_ptr_t fptr_) + : fptr(fptr_) {} + + result_type operator()(A a) const + { return fptr(a); } + + func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, typename A> +inline function_ptr<RT, A> +bind(RT(*fptr)(A)) +{ + return function_ptr<RT, A>(fptr); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Function pointer binder (specialization for 2 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, typename A, typename B> +struct function_ptr_action<RT, + A, B, nil_t, +#if PHOENIX_LIMIT > 3 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 6 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif +#endif +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(*func_ptr_t)(A, B); + + template <typename A_, typename B_> + struct result { typedef result_type type; }; + + function_ptr_action(func_ptr_t fptr_) + : fptr(fptr_) {} + + result_type operator()(A a, B b) const + { return fptr(a, b); } + + func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, typename A, typename B> +inline function_ptr<RT, A, B> +bind(RT(*fptr)(A, B)) +{ + return function_ptr<RT, A, B>(fptr); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Function pointer binder (specialization for 3 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, typename A, typename B, typename C> +struct function_ptr_action<RT, + A, B, C, +#if PHOENIX_LIMIT > 3 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 6 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif +#endif +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(*func_ptr_t)(A, B, C); + + template <typename A_, typename B_, typename C_> + struct result { typedef result_type type; }; + + function_ptr_action(func_ptr_t fptr_) + : fptr(fptr_) {} + + result_type operator()(A a, B b, C c) const + { return fptr(a, b, c); } + + func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, typename A, typename B, typename C> +inline function_ptr<RT, A, B, C> +bind(RT(*fptr)(A, B, C)) +{ + return function_ptr<RT, A, B, C>(fptr); +} + +#if PHOENIX_LIMIT > 3 +/////////////////////////////////////////////////////////////////////////////// +// +// Function pointer binder (specialization for 4 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, typename A, typename B, typename C, typename D> +struct function_ptr_action<RT, + A, B, C, D, nil_t, nil_t, +#if PHOENIX_LIMIT > 6 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(*func_ptr_t)(A, B, C, D); + + template <typename A_, typename B_, typename C_, typename D_> + struct result { typedef result_type type; }; + + function_ptr_action(func_ptr_t fptr_) + : fptr(fptr_) {} + + result_type operator()(A a, B b, C c, D d) const + { return fptr(a, b, c, d); } + + func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, typename A, typename B, typename C, typename D> +inline function_ptr<RT, A, B, C, D> +bind(RT(*fptr)(A, B, C, D)) +{ + return function_ptr<RT, A, B, C, D>(fptr); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Function pointer binder (specialization for 5 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, + typename A, typename B, typename C, typename D, typename E +> +struct function_ptr_action<RT, + A, B, C, D, E, nil_t, +#if PHOENIX_LIMIT > 6 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(*func_ptr_t)(A, B, C, D, E); + + template < + typename A_, typename B_, typename C_, typename D_, typename E_ + > + struct result { typedef result_type type; }; + + function_ptr_action(func_ptr_t fptr_) + : fptr(fptr_) {} + + result_type operator()( + A a, B b, C c, D d, E e + ) const + { return fptr(a, b, c, d, e); } + + func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, + typename A, typename B, typename C, typename D, typename E +> +inline function_ptr<RT, A, B, C, D, E> +bind(RT(*fptr)(A, B, C, D, E)) +{ + return function_ptr<RT, A, B, C, D, E>(fptr); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Function pointer binder (specialization for 6 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, + typename A, typename B, typename C, typename D, typename E, + typename F +> +struct function_ptr_action<RT, + A, B, C, D, E, F, +#if PHOENIX_LIMIT > 6 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(*func_ptr_t)(A, B, C, D, E, F); + + template < + typename A_, typename B_, typename C_, typename D_, typename E_, + typename F_ + > + struct result { typedef result_type type; }; + + function_ptr_action(func_ptr_t fptr_) + : fptr(fptr_) {} + + result_type operator()( + A a, B b, C c, D d, E e, + F f + ) const + { return fptr(a, b, c, d, e, f); } + + func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, + typename A, typename B, typename C, typename D, typename E, + typename F +> +inline function_ptr<RT, A, B, C, D, E, F> +bind(RT(*fptr)(A, B, C, D, E, F)) +{ + return function_ptr<RT, A, B, C, D, E, F>(fptr); +} + +#if PHOENIX_LIMIT > 6 +/////////////////////////////////////////////////////////////////////////////// +// +// Function pointer binder (specialization for 7 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G +> +struct function_ptr_action<RT, + A, B, C, D, E, F, G, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(*func_ptr_t)(A, B, C, D, E, F, G); + + template < + typename A_, typename B_, typename C_, typename D_, typename E_, + typename F_, typename G_ + > + struct result { typedef result_type type; }; + + function_ptr_action(func_ptr_t fptr_) + : fptr(fptr_) {} + + result_type operator()( + A a, B b, C c, D d, E e, + F f, G g + ) const + { return fptr(a, b, c, d, e, f, g); } + + func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G +> +inline function_ptr<RT, A, B, C, D, E, F, G> +bind(RT(*fptr)(A, B, C, D, E, F, G)) +{ + return function_ptr<RT, A, B, C, D, E, F, G>(fptr); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Function pointer binder (specialization for 8 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H +> +struct function_ptr_action<RT, + A, B, C, D, E, F, G, H, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(*func_ptr_t)(A, B, C, D, E, F, G, H); + + template < + typename A_, typename B_, typename C_, typename D_, typename E_, + typename F_, typename G_, typename H_ + > + struct result { typedef result_type type; }; + + function_ptr_action(func_ptr_t fptr_) + : fptr(fptr_) {} + + result_type operator()( + A a, B b, C c, D d, E e, + F f, G g, H h + ) const + { return fptr(a, b, c, d, e, f, g, h); } + + func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H +> +inline function_ptr<RT, A, B, C, D, E, F, G, H> +bind(RT(*fptr)(A, B, C, D, E, F, G, H)) +{ + return function_ptr<RT, A, B, C, D, E, F, G, H>(fptr); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Function pointer binder (specialization for 9 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I +> +struct function_ptr_action<RT, + A, B, C, D, E, F, G, H, I, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(*func_ptr_t)(A, B, C, D, E, F, G, H, I); + + template < + typename A_, typename B_, typename C_, typename D_, typename E_, + typename F_, typename G_, typename H_, typename I_ + > + struct result { typedef result_type type; }; + + function_ptr_action(func_ptr_t fptr_) + : fptr(fptr_) {} + + result_type operator()( + A a, B b, C c, D d, E e, + F f, G g, H h, I i + ) const + { return fptr(a, b, c, d, e, f, g, h, i); } + + func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I +> +inline function_ptr<RT, A, B, C, D, E, F, G, H, I> +bind(RT(*fptr)(A, B, C, D, E, F, G, H, I)) +{ + return function_ptr<RT, A, B, C, D, E, F, G, H, I>(fptr); +} + +#if PHOENIX_LIMIT > 9 +/////////////////////////////////////////////////////////////////////////////// +// +// Function pointer binder (specialization for 10 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J +> +struct function_ptr_action<RT, + A, B, C, D, E, F, G, H, I, J, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(*func_ptr_t)(A, B, C, D, E, F, G, H, I, J); + + template < + typename A_, typename B_, typename C_, typename D_, typename E_, + typename F_, typename G_, typename H_, typename I_, typename J_ + > + struct result { typedef result_type type; }; + + function_ptr_action(func_ptr_t fptr_) + : fptr(fptr_) {} + + result_type operator()( + A a, B b, C c, D d, E e, + F f, G g, H h, I i, J j + ) const + { return fptr(a, b, c, d, e, f, g, h, i, j); } + + func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J +> +inline function_ptr<RT, A, B, C, D, E, F, G, H, I, J> +bind(RT(*fptr)(A, B, C, D, E, F, G, H, I, J)) +{ + return function_ptr<RT, A, B, C, D, E, F, G, H, I, J>(fptr); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Function pointer binder (specialization for 11 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K +> +struct function_ptr_action<RT, + A, B, C, D, E, F, G, H, I, J, K, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(*func_ptr_t)(A, B, C, D, E, F, G, H, I, J, K); + + template < + typename A_, typename B_, typename C_, typename D_, typename E_, + typename F_, typename G_, typename H_, typename I_, typename J_, + typename K_ + > + struct result { typedef result_type type; }; + + function_ptr_action(func_ptr_t fptr_) + : fptr(fptr_) {} + + result_type operator()( + A a, B b, C c, D d, E e, + F f, G g, H h, I i, J j, + K k + ) const + { return fptr(a, b, c, d, e, f, g, h, i, j, k); } + + func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K +> +inline function_ptr<RT, A, B, C, D, E, F, G, H, I, J, K> +bind(RT(*fptr)(A, B, C, D, E, F, G, H, I, J, K)) +{ + return function_ptr<RT, A, B, C, D, E, F, G, H, I, J, K>(fptr); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Function pointer binder (specialization for 12 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L +> +struct function_ptr_action<RT, + A, B, C, D, E, F, G, H, I, J, K, L, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(*func_ptr_t)(A, B, C, D, E, F, G, H, I, J, K, L); + + template < + typename A_, typename B_, typename C_, typename D_, typename E_, + typename F_, typename G_, typename H_, typename I_, typename J_, + typename K_, typename L_ + > + struct result { typedef result_type type; }; + + function_ptr_action(func_ptr_t fptr_) + : fptr(fptr_) {} + + result_type operator()( + A a, B b, C c, D d, E e, + F f, G g, H h, I i, J j, + K k, L l + ) const + { return fptr(a, b, c, d, e, f, g, h, i, j, k, l); } + + func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L +> +inline function_ptr<RT, A, B, C, D, E, F, G, H, I, J, K, L> +bind(RT(*fptr)(A, B, C, D, E, F, G, H, I, J, K, L)) +{ + return function_ptr<RT, A, B, C, D, E, F, G, H, I, J, K, L>(fptr); +} + +#if PHOENIX_LIMIT > 12 +/////////////////////////////////////////////////////////////////////////////// +// +// Function pointer binder (specialization for 13 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M +> +struct function_ptr_action<RT, + A, B, C, D, E, F, G, H, I, J, K, L, M, nil_t, nil_t, nil_t> { + + typedef RT result_type; + typedef RT(*func_ptr_t)(A, B, C, D, E, F, G, H, I, J, K, L, M); + + template < + typename A_, typename B_, typename C_, typename D_, typename E_, + typename F_, typename G_, typename H_, typename I_, typename J_, + typename K_, typename L_, typename M_ + > + struct result { typedef result_type type; }; + + function_ptr_action(func_ptr_t fptr_) + : fptr(fptr_) {} + + result_type operator()( + A a, B b, C c, D d, E e, + F f, G g, H h, I i, J j, + K k, L l, M m + ) const + { return fptr(a, b, c, d, e, f, g, h, i, j, k, l, m); } + + func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M +> +inline function_ptr<RT, A, B, C, D, E, F, G, H, I, J, K, L, M> +bind(RT(*fptr)(A, B, C, D, E, F, G, H, I, J, K, L, M)) +{ + return function_ptr<RT, A, B, C, D, E, F, G, H, I, J, K, L, M>(fptr); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Function pointer binder (specialization for 14 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M, typename N +> +struct function_ptr_action<RT, + A, B, C, D, E, F, G, H, I, J, K, L, M, N, nil_t, nil_t> { + + typedef RT result_type; + typedef RT(*func_ptr_t)(A, B, C, D, E, F, G, H, I, J, K, L, M, N); + + template < + typename A_, typename B_, typename C_, typename D_, typename E_, + typename F_, typename G_, typename H_, typename I_, typename J_, + typename K_, typename L_, typename M_, typename N_ + > + struct result { typedef result_type type; }; + + function_ptr_action(func_ptr_t fptr_) + : fptr(fptr_) {} + + result_type operator()( + A a, B b, C c, D d, E e, + F f, G g, H h, I i, J j, + K k, L l, M m, N n + ) const + { return fptr(a, b, c, d, e, f, g, h, i, j, k, l, m, n); } + + func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M, typename N +> +inline function_ptr<RT, A, B, C, D, E, F, G, H, I, J, K, L, M, N> +bind(RT(*fptr)(A, B, C, D, E, F, G, H, I, J, K, L, M, N)) +{ + return function_ptr<RT, A, B, C, D, E, F, G, H, I, J, K, L, M, N>(fptr); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Function pointer binder (specialization for 15 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M, typename N, typename O +> +struct function_ptr_action<RT, + A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, nil_t> { + + typedef RT result_type; + typedef RT(*func_ptr_t)(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O); + + template < + typename A_, typename B_, typename C_, typename D_, typename E_, + typename F_, typename G_, typename H_, typename I_, typename J_, + typename K_, typename L_, typename M_, typename N_, typename O_ + > + struct result { typedef result_type type; }; + + function_ptr_action(func_ptr_t fptr_) + : fptr(fptr_) {} + + result_type operator()( + A a, B b, C c, D d, E e, + F f, G g, H h, I i, J j, + K k, L l, M m, N n, O o + ) const + { return fptr(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o); } + + func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M, typename N, typename O +> +inline function_ptr<RT, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O> +bind(RT(*fptr)(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O)) +{ + return function_ptr<RT, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O>(fptr); +} + +#endif +#endif +#endif +#endif +/////////////////////////////////////////////////////////////////////////////// +// +// Member function pointer binder (main class) +// +/////////////////////////////////////////////////////////////////////////////// +template < + typename RT, + typename ClassT + , typename A = nil_t + , typename B = nil_t + , typename C = nil_t + +#if PHOENIX_LIMIT > 3 + , typename D = nil_t + , typename E = nil_t + , typename F = nil_t + +#if PHOENIX_LIMIT > 6 + , typename G = nil_t + , typename H = nil_t + , typename I = nil_t + +#if PHOENIX_LIMIT > 9 + , typename J = nil_t + , typename K = nil_t + , typename L = nil_t + +#if PHOENIX_LIMIT > 12 + , typename M = nil_t + , typename N = nil_t + , typename O = nil_t + +#endif +#endif +#endif +#endif + + , typename NU = nil_t // Not used +> +struct member_function_ptr_action; + +////////////////////////////////// +template < + typename RT, + typename ClassT + , typename A = nil_t + , typename B = nil_t + , typename C = nil_t + +#if PHOENIX_LIMIT > 3 + , typename D = nil_t + , typename E = nil_t + , typename F = nil_t + +#if PHOENIX_LIMIT > 6 + , typename G = nil_t + , typename H = nil_t + , typename I = nil_t + +#if PHOENIX_LIMIT > 9 + , typename J = nil_t + , typename K = nil_t + , typename L = nil_t + +#if PHOENIX_LIMIT > 12 + , typename M = nil_t + , typename N = nil_t + , typename O = nil_t + +#endif +#endif +#endif +#endif +> +struct member_function_ptr +: public function<member_function_ptr_action<RT, ClassT + , A, B, C +#if PHOENIX_LIMIT > 3 + , D, E, F +#if PHOENIX_LIMIT > 6 + , G, H, I +#if PHOENIX_LIMIT > 9 + , J, K, L +#if PHOENIX_LIMIT > 12 + , M, N, O +#endif +#endif +#endif +#endif + > > { + + typedef member_function_ptr_action<RT, ClassT + , A, B, C +#if PHOENIX_LIMIT > 3 + , D, E, F +#if PHOENIX_LIMIT > 6 + , G, H, I +#if PHOENIX_LIMIT > 9 + , J, K, L +#if PHOENIX_LIMIT > 12 + , M, N, O +#endif +#endif +#endif +#endif + > action_t; + + template <typename FPT> + member_function_ptr(FPT fp) + : function<action_t>(action_t(fp)) {} +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// Member function pointer binder (specialization for 0 arg) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, typename ClassT> +struct member_function_ptr_action<RT, ClassT, + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 3 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 6 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif +#endif +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(ClassT::*mf)(); + typedef RT(ClassT::*cmf)() const; + typedef typename boost::mpl::if_<boost::is_const<ClassT>, cmf, mf>::type + mem_func_ptr_t; + + template <typename CT> + struct result { typedef result_type type; }; + + member_function_ptr_action(mem_func_ptr_t fptr_) + : fptr(fptr_) {} + + template <typename CT> + result_type operator()(CT& obj) const + { return (impl::as_ptr<CT>::get(obj)->*fptr)(); } + + mem_func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, typename ClassT> +inline member_function_ptr<RT, ClassT> +bind(RT(ClassT::*fptr)()) +{ + return member_function_ptr<RT, ClassT>(fptr); +} + +template <typename RT, typename ClassT> +inline member_function_ptr<RT, ClassT const> +bind(RT(ClassT::*fptr)() const) +{ + return member_function_ptr<RT, ClassT const>(fptr); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Member function pointer binder (specialization for 1 arg) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, typename ClassT, typename A> +struct member_function_ptr_action<RT, ClassT, + A, nil_t, nil_t, +#if PHOENIX_LIMIT > 3 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 6 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif +#endif +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(ClassT::*mf)(A); + typedef RT(ClassT::*cmf)(A) const; + typedef typename boost::mpl::if_<boost::is_const<ClassT>, cmf, mf>::type + mem_func_ptr_t; + + template <typename CT, typename A_> + struct result { typedef result_type type; }; + + member_function_ptr_action(mem_func_ptr_t fptr_) + : fptr(fptr_) {} + + template <typename CT> + result_type operator()(CT& obj, A a) const + { return (impl::as_ptr<CT>::get(obj)->*fptr)(a); } + + mem_func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, typename ClassT, typename A> +inline member_function_ptr<RT, ClassT, A> +bind(RT(ClassT::*fptr)(A)) +{ + return member_function_ptr<RT, ClassT, A>(fptr); +} + +////////////////////////////////// +template <typename RT, typename ClassT, typename A> +inline member_function_ptr<RT, ClassT const, A> +bind(RT(ClassT::*fptr)(A) const) +{ + return member_function_ptr<RT, ClassT const, A>(fptr); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Member function pointer binder (specialization for 2 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, typename ClassT, typename A, typename B> +struct member_function_ptr_action<RT, ClassT, + A, B, nil_t, +#if PHOENIX_LIMIT > 3 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 6 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif +#endif +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(ClassT::*mf)(A, B); + typedef RT(ClassT::*cmf)(A, B) const; + typedef typename boost::mpl::if_<boost::is_const<ClassT>, cmf, mf>::type + mem_func_ptr_t; + + template <typename CT, typename A_, typename B_> + struct result { typedef result_type type; }; + + member_function_ptr_action(mem_func_ptr_t fptr_) + : fptr(fptr_) {} + + template <typename CT> + result_type operator()(CT& obj, A a, B b) const + { return (impl::as_ptr<CT>::get(obj)->*fptr)(a, b); } + + mem_func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, typename ClassT, typename A, typename B> +inline member_function_ptr<RT, ClassT, A, B> +bind(RT(ClassT::*fptr)(A, B)) +{ + return member_function_ptr<RT, ClassT, A, B>(fptr); +} + +////////////////////////////////// +template <typename RT, typename ClassT, typename A, typename B> +inline member_function_ptr<RT, ClassT const, A, B> +bind(RT(ClassT::*fptr)(A, B) const) +{ + return member_function_ptr<RT, ClassT const, A, B>(fptr); +} + +#if PHOENIX_LIMIT > 3 +/////////////////////////////////////////////////////////////////////////////// +// +// Member function pointer binder (specialization for 3 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, typename ClassT, typename A, typename B, typename C> +struct member_function_ptr_action<RT, ClassT, + A, B, C, nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 6 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(ClassT::*mf)(A, B, C); + typedef RT(ClassT::*cmf)(A, B, C) const; + typedef typename boost::mpl::if_<boost::is_const<ClassT>, cmf, mf>::type + mem_func_ptr_t; + + template <typename CT, typename A_, typename B_, typename C_> + struct result { typedef result_type type; }; + + member_function_ptr_action(mem_func_ptr_t fptr_) + : fptr(fptr_) {} + + template <typename CT> + result_type operator()(CT& obj, A a, B b, C c) const + { return (impl::as_ptr<CT>::get(obj)->*fptr)(a, b, c); } + + mem_func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, typename ClassT, typename A, typename B, typename C> +inline member_function_ptr<RT, ClassT, A, B, C> +bind(RT(ClassT::*fptr)(A, B, C)) +{ + return member_function_ptr<RT, ClassT, A, B, C>(fptr); +} + +////////////////////////////////// +template <typename RT, typename ClassT, typename A, typename B, typename C> +inline member_function_ptr<RT, ClassT const, A, B, C> +bind(RT(ClassT::*fptr)(A, B, C) const) +{ + return member_function_ptr<RT, ClassT const, A, B, C>(fptr); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Member function pointer binder (specialization for 4 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D +> +struct member_function_ptr_action<RT, ClassT, + A, B, C, D, nil_t, nil_t, +#if PHOENIX_LIMIT > 6 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(ClassT::*mf)(A, B, C, D); + typedef RT(ClassT::*cmf)(A, B, C, D) const; + typedef typename boost::mpl::if_<boost::is_const<ClassT>, cmf, mf>::type + mem_func_ptr_t; + + template <typename CT, + typename A_, typename B_, typename C_, typename D_ + > + struct result { typedef result_type type; }; + + member_function_ptr_action(mem_func_ptr_t fptr_) + : fptr(fptr_) {} + + template <typename CT> + result_type operator()(CT& obj, + A a, B b, C c, D d + ) const + { return (impl::as_ptr<CT>::get(obj)->*fptr)(a, b, c, d); } + + mem_func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D +> +inline member_function_ptr<RT, ClassT, A, B, C, D> +bind(RT(ClassT::*fptr)(A, B, C, D)) +{ + return member_function_ptr< + RT, ClassT, A, B, C, D>(fptr); +} + +////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D +> +inline member_function_ptr<RT, ClassT const, A, B, C, D> +bind(RT(ClassT::*fptr)(A, B, C, D) const) +{ + return member_function_ptr< + RT, ClassT const, A, B, C, D>(fptr); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Member function pointer binder (specialization for 5 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E +> +struct member_function_ptr_action<RT, ClassT, + A, B, C, D, E, nil_t, +#if PHOENIX_LIMIT > 6 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(ClassT::*mf)(A, B, C, D, E); + typedef RT(ClassT::*cmf)(A, B, C, D, E) const; + typedef typename boost::mpl::if_<boost::is_const<ClassT>, cmf, mf>::type + mem_func_ptr_t; + + template <typename CT, + typename A_, typename B_, typename C_, typename D_, + typename E_ + > + struct result { typedef result_type type; }; + + member_function_ptr_action(mem_func_ptr_t fptr_) + : fptr(fptr_) {} + + template <typename CT> + result_type operator()(CT& obj, + A a, B b, C c, D d, E e + ) const + { return (impl::as_ptr<CT>::get(obj)->*fptr)(a, b, c, d, e); } + + mem_func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E +> +inline member_function_ptr<RT, ClassT, A, B, C, D, E> +bind(RT(ClassT::*fptr)(A, B, C, D, E)) +{ + return member_function_ptr< + RT, ClassT, A, B, C, D, E>(fptr); +} + +////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E +> +inline member_function_ptr<RT, ClassT const, A, B, C, D, E> +bind(RT(ClassT::*fptr)(A, B, C, D, E) const) +{ + return member_function_ptr< + RT, ClassT const, A, B, C, D, E>(fptr); +} + +#if PHOENIX_LIMIT > 6 +/////////////////////////////////////////////////////////////////////////////// +// +// Member function pointer binder (specialization for 6 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F +> +struct member_function_ptr_action<RT, ClassT, + A, B, C, D, E, F, nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(ClassT::*mf)(A, B, C, D, E, F); + typedef RT(ClassT::*cmf)(A, B, C, D, E, F) const; + typedef typename boost::mpl::if_<boost::is_const<ClassT>, cmf, mf>::type + mem_func_ptr_t; + + template <typename CT, + typename A_, typename B_, typename C_, typename D_, + typename E_, typename F_ + > + struct result { typedef result_type type; }; + + member_function_ptr_action(mem_func_ptr_t fptr_) + : fptr(fptr_) {} + + template <typename CT> + result_type operator()(CT& obj, + A a, B b, C c, D d, E e, F f + ) const + { return (impl::as_ptr<CT>::get(obj)->*fptr)(a, b, c, d, e, f); } + + mem_func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F +> +inline member_function_ptr<RT, ClassT, A, B, C, D, E, F> +bind(RT(ClassT::*fptr)(A, B, C, D, E, F)) +{ + return member_function_ptr< + RT, ClassT, A, B, C, D, E, F>(fptr); +} + +////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F +> +inline member_function_ptr<RT, ClassT const, A, B, C, D, E, F> +bind(RT(ClassT::*fptr)(A, B, C, D, E, F) const) +{ + return member_function_ptr< + RT, ClassT const, A, B, C, D, E, F>(fptr); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Member function pointer binder (specialization for 7 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G +> +struct member_function_ptr_action<RT, ClassT, + A, B, C, D, E, F, G, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(ClassT::*mf)(A, B, C, D, E, F, G); + typedef RT(ClassT::*cmf)(A, B, C, D, E, F, G) const; + typedef typename boost::mpl::if_<boost::is_const<ClassT>, cmf, mf>::type + mem_func_ptr_t; + + template <typename CT, + typename A_, typename B_, typename C_, typename D_, + typename E_, typename F_, typename G_ + > + struct result { typedef result_type type; }; + + member_function_ptr_action(mem_func_ptr_t fptr_) + : fptr(fptr_) {} + + template <typename CT> + result_type operator()(CT& obj, + A a, B b, C c, D d, E e, F f, G g + ) const + { return (impl::as_ptr<CT>::get(obj)->*fptr)(a, b, c, d, e, f, g); } + + mem_func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G +> +inline member_function_ptr<RT, ClassT, A, B, C, D, E, F, G> +bind(RT(ClassT::*fptr)(A, B, C, D, E, F, G)) +{ + return member_function_ptr< + RT, ClassT, A, B, C, D, E, F, G>(fptr); +} + +////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G +> +inline member_function_ptr<RT, ClassT const, A, B, C, D, E, F, G> +bind(RT(ClassT::*fptr)(A, B, C, D, E, F, G) const) +{ + return member_function_ptr< + RT, ClassT const, A, B, C, D, E, F, G>(fptr); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Member function pointer binder (specialization for 8 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H +> +struct member_function_ptr_action<RT, ClassT, + A, B, C, D, E, F, G, H, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(ClassT::*mf)(A, B, C, D, E, F, G, H); + typedef RT(ClassT::*cmf)(A, B, C, D, E, F, G, H) const; + typedef typename boost::mpl::if_<boost::is_const<ClassT>, cmf, mf>::type + mem_func_ptr_t; + + template <typename CT, + typename A_, typename B_, typename C_, typename D_, + typename E_, typename F_, typename G_, typename H_ + > + struct result { typedef result_type type; }; + + member_function_ptr_action(mem_func_ptr_t fptr_) + : fptr(fptr_) {} + + template <typename CT> + result_type operator()(CT& obj, + A a, B b, C c, D d, E e, F f, G g, H h + ) const + { return (impl::as_ptr<CT>::get(obj)->*fptr)(a, b, c, d, e, f, g, h); } + + mem_func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H +> +inline member_function_ptr<RT, ClassT, A, B, C, D, E, F, G, H> +bind(RT(ClassT::*fptr)(A, B, C, D, E, F, G, H)) +{ + return member_function_ptr< + RT, ClassT, A, B, C, D, E, F, G, H>(fptr); +} + +////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H +> +inline member_function_ptr<RT, ClassT const, A, B, C, D, E, F, G, H> +bind(RT(ClassT::*fptr)(A, B, C, D, E, F, G, H) const) +{ + return member_function_ptr< + RT, ClassT const, A, B, C, D, E, F, G, H>(fptr); +} + +#if PHOENIX_LIMIT > 9 +/////////////////////////////////////////////////////////////////////////////// +// +// Member function pointer binder (specialization for 9 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I +> +struct member_function_ptr_action<RT, ClassT, + A, B, C, D, E, F, G, H, I, nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(ClassT::*mf)(A, B, C, D, E, F, G, H, I); + typedef RT(ClassT::*cmf)(A, B, C, D, E, F, G, H, I) const; + typedef typename boost::mpl::if_<boost::is_const<ClassT>, cmf, mf>::type + mem_func_ptr_t; + + template <typename CT, + typename A_, typename B_, typename C_, typename D_, + typename E_, typename F_, typename G_, typename H_, typename I_ + > + struct result { typedef result_type type; }; + + member_function_ptr_action(mem_func_ptr_t fptr_) + : fptr(fptr_) {} + + template <typename CT> + result_type operator()(CT& obj, + A a, B b, C c, D d, E e, F f, G g, H h, I i + ) const + { return (impl::as_ptr<CT>::get(obj)->*fptr)(a, b, c, d, e, f, g, h, i); } + + mem_func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I +> +inline member_function_ptr<RT, ClassT, A, B, C, D, E, F, G, H, I> +bind(RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I)) +{ + return member_function_ptr< + RT, ClassT, A, B, C, D, E, F, G, H, I>(fptr); +} + +////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I +> +inline member_function_ptr<RT, ClassT const, A, B, C, D, E, F, G, H, I> +bind(RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I) const) +{ + return member_function_ptr< + RT, ClassT const, A, B, C, D, E, F, G, H, I>(fptr); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Member function pointer binder (specialization for 10 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J +> +struct member_function_ptr_action<RT, ClassT, + A, B, C, D, E, F, G, H, I, J, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(ClassT::*mf)(A, B, C, D, E, F, G, H, I, J); + typedef RT(ClassT::*cmf)(A, B, C, D, E, F, G, H, I, J) const; + typedef typename boost::mpl::if_<boost::is_const<ClassT>, cmf, mf>::type + mem_func_ptr_t; + + template <typename CT, + typename A_, typename B_, typename C_, typename D_, + typename E_, typename F_, typename G_, typename H_, typename I_, + typename J_ + > + struct result { typedef result_type type; }; + + member_function_ptr_action(mem_func_ptr_t fptr_) + : fptr(fptr_) {} + + template <typename CT> + result_type operator()(CT& obj, + A a, B b, C c, D d, E e, F f, G g, H h, I i, J j + ) const + { + return (impl::as_ptr<CT>::get(obj)->*fptr) + (a, b, c, d, e, f, g, h, i, j); + } + + mem_func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J +> +inline member_function_ptr<RT, ClassT, A, B, C, D, E, F, G, H, I, J> +bind(RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I, J)) +{ + return member_function_ptr< + RT, ClassT, A, B, C, D, E, F, G, H, I, J>(fptr); +} + +////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J +> +inline member_function_ptr<RT, ClassT const, A, B, C, D, E, F, G, H, I, J> +bind(RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I, J) const) +{ + return member_function_ptr< + RT, ClassT const, A, B, C, D, E, F, G, H, I, J>(fptr); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Member function pointer binder (specialization for 11 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K +> +struct member_function_ptr_action<RT, ClassT, + A, B, C, D, E, F, G, H, I, J, K, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(ClassT::*mf)(A, B, C, D, E, F, G, H, I, J, K); + typedef RT(ClassT::*cmf)(A, B, C, D, E, F, G, H, I, J, K) const; + typedef typename boost::mpl::if_<boost::is_const<ClassT>, cmf, mf>::type + mem_func_ptr_t; + + template <typename CT, + typename A_, typename B_, typename C_, typename D_, + typename E_, typename F_, typename G_, typename H_, typename I_, + typename J_, typename K_ + > + struct result { typedef result_type type; }; + + member_function_ptr_action(mem_func_ptr_t fptr_) + : fptr(fptr_) {} + + template <typename CT> + result_type operator()(CT& obj, + A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k + ) const + { + return (impl::as_ptr<CT>::get(obj)->*fptr) + (a, b, c, d, e, f, g, h, i, j, k); + } + + mem_func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K +> +inline member_function_ptr<RT, ClassT, A, B, C, D, E, F, G, H, I, J, K> +bind(RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I, J, K)) +{ + return member_function_ptr< + RT, ClassT, A, B, C, D, E, F, G, H, I, J, K>(fptr); +} + +////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K +> +inline member_function_ptr<RT, ClassT const, A, B, C, D, E, F, G, H, I, J, K> +bind(RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I, J, K) const) +{ + return member_function_ptr< + RT, ClassT const, A, B, C, D, E, F, G, H, I, J, K>(fptr); +} + +#if PHOENIX_LIMIT > 12 +/////////////////////////////////////////////////////////////////////////////// +// +// Member function pointer binder (specialization for 12 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K, typename L +> +struct member_function_ptr_action<RT, ClassT, + A, B, C, D, E, F, G, H, I, J, K, L, nil_t, nil_t, nil_t, nil_t> { + + typedef RT result_type; + typedef RT(ClassT::*mf)(A, B, C, D, E, F, G, H, I, J, K, L); + typedef RT(ClassT::*cmf)(A, B, C, D, E, F, G, H, I, J, K, L) const; + typedef typename boost::mpl::if_<boost::is_const<ClassT>, cmf, mf>::type + mem_func_ptr_t; + + template <typename CT, + typename A_, typename B_, typename C_, typename D_, + typename E_, typename F_, typename G_, typename H_, typename I_, + typename J_, typename K_, typename L_ + > + struct result { typedef result_type type; }; + + member_function_ptr_action(mem_func_ptr_t fptr_) + : fptr(fptr_) {} + + template <typename CT> + result_type operator()(CT& obj, + A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l + ) const + { + return (impl::as_ptr<CT>::get(obj)->*fptr) + (a, b, c, d, e, f, g, h, i, j, k, l); + } + + mem_func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K, typename L +> +inline member_function_ptr<RT, ClassT, A, B, C, D, E, F, G, H, I, J, K, L> +bind(RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I, J, K, L)) +{ + return member_function_ptr< + RT, ClassT, A, B, C, D, E, F, G, H, I, J, K, L>(fptr); +} + +////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K, typename L +> +inline member_function_ptr<RT, ClassT const, A, B, C, D, E, F, G, H, I, J, K, L> +bind(RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I, J, K, L) const) +{ + return member_function_ptr< + RT, ClassT const, A, B, C, D, E, F, G, H, I, J, K, L>(fptr); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Member function pointer binder (specialization for 13 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K, typename L, typename M +> +struct member_function_ptr_action<RT, ClassT, + A, B, C, D, E, F, G, H, I, J, K, L, M, nil_t, nil_t, nil_t> { + + typedef RT result_type; + typedef RT(ClassT::*mf)(A, B, C, D, E, F, G, H, I, J, K, L, M); + typedef RT(ClassT::*cmf)(A, B, C, D, E, F, G, H, I, J, K, L, M) const; + typedef typename boost::mpl::if_<boost::is_const<ClassT>, cmf, mf>::type + mem_func_ptr_t; + + template <typename CT, + typename A_, typename B_, typename C_, typename D_, + typename E_, typename F_, typename G_, typename H_, typename I_, + typename J_, typename K_, typename L_, typename M_ + > + struct result { typedef result_type type; }; + + member_function_ptr_action(mem_func_ptr_t fptr_) + : fptr(fptr_) {} + + template <typename CT> + result_type operator()(CT& obj, + A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, M m + ) const + { + return (impl::as_ptr<CT>::get(obj)->*fptr) + (a, b, c, d, e, f, g, h, i, j, k, l, m); + } + + mem_func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K, typename L, typename M +> +inline member_function_ptr<RT, ClassT, A, B, C, D, E, F, G, H, I, J, K, L, M> +bind(RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I, J, K, L, M)) +{ + return member_function_ptr< + RT, ClassT, A, B, C, D, E, F, G, H, I, J, K, L, M>(fptr); +} + +////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K, typename L, typename M +> +inline member_function_ptr<RT, ClassT const, A, B, C, D, E, F, G, H, I, J, K, L, M> +bind(RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I, J, K, L, M) const) +{ + return member_function_ptr< + RT, ClassT const, A, B, C, D, E, F, G, H, I, J, K, L, M>(fptr); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Member function pointer binder (specialization for 14 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K, typename L, typename M, typename N +> +struct member_function_ptr_action<RT, ClassT, + A, B, C, D, E, F, G, H, I, J, K, L, M, N, nil_t, nil_t> { + + typedef RT result_type; + typedef RT(ClassT::*mf)(A, B, C, D, E, F, G, H, I, J, K, L, M, N); + typedef RT(ClassT::*cmf)(A, B, C, D, E, F, G, H, I, J, K, L, M, N) const; + typedef typename boost::mpl::if_<boost::is_const<ClassT>, cmf, mf>::type + mem_func_ptr_t; + + template <typename CT, + typename A_, typename B_, typename C_, typename D_, + typename E_, typename F_, typename G_, typename H_, typename I_, + typename J_, typename K_, typename L_, typename M_, typename N_ + > + struct result { typedef result_type type; }; + + member_function_ptr_action(mem_func_ptr_t fptr_) + : fptr(fptr_) {} + + template <typename CT> + result_type operator()(CT& obj, + A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, M m, N n + ) const + { + return (impl::as_ptr<CT>::get(obj)->*fptr) + (a, b, c, d, e, f, g, h, i, j, k, l, m, n); + } + + mem_func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K, typename L, typename M, typename N +> +inline member_function_ptr<RT, ClassT, A, B, C, D, E, F, G, H, I, J, K, L, M, N> +bind(RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I, J, K, L, M, N)) +{ + return member_function_ptr< + RT, ClassT, A, B, C, D, E, F, G, H, I, J, K, L, M, N>(fptr); +} + +////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K, typename L, typename M, typename N +> +inline member_function_ptr<RT, ClassT const, A, B, C, D, E, F, G, H, I, J, K, L, M, N> +bind(RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I, J, K, L, M, N) const) +{ + return member_function_ptr< + RT, ClassT const, A, B, C, D, E, F, G, H, I, J, K, L, M, N>(fptr); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Member function pointer binder (specialization for 15 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K, typename L, typename M, typename N, + typename O +> +struct member_function_ptr_action<RT, ClassT, + A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, nil_t> { + + typedef RT result_type; + typedef RT(ClassT::*mf)(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O); + typedef RT(ClassT::*cmf)(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O) const; + typedef typename boost::mpl::if_<boost::is_const<ClassT>, cmf, mf>::type + mem_func_ptr_t; + + template <typename CT, + typename A_, typename B_, typename C_, typename D_, + typename E_, typename F_, typename G_, typename H_, typename I_, + typename J_, typename K_, typename L_, typename M_, typename N_, + typename O_ + > + struct result { typedef result_type type; }; + + member_function_ptr_action(mem_func_ptr_t fptr_) + : fptr(fptr_) {} + + template <typename CT> + result_type operator()(CT& obj, + A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, M m, N n, O o + ) const + { + return (impl::as_ptr<CT>::get(obj)->*fptr) + (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o); + } + + mem_func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K, typename L, typename M, typename N, + typename O +> +inline member_function_ptr<RT, ClassT, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O> +bind(RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O)) +{ + return member_function_ptr< + RT, ClassT, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O>(fptr); +} + +////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K, typename L, typename M, typename N, + typename O +> +inline member_function_ptr<RT, ClassT const, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O> +bind(RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O) const) +{ + return member_function_ptr< + RT, ClassT const, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O>(fptr); +} + +#endif +#endif +#endif +#endif + +/////////////////////////////////////////////////////////////////////////////// +// +// Bound member function binder (main class) +// +/////////////////////////////////////////////////////////////////////////////// +template < + typename RT, + typename ClassT + , typename A = nil_t + , typename B = nil_t + , typename C = nil_t + +#if PHOENIX_LIMIT > 3 + , typename D = nil_t + , typename E = nil_t + , typename F = nil_t + +#if PHOENIX_LIMIT > 6 + , typename G = nil_t + , typename H = nil_t + , typename I = nil_t + +#if PHOENIX_LIMIT > 9 + , typename J = nil_t + , typename K = nil_t + , typename L = nil_t + +#if PHOENIX_LIMIT > 12 + , typename M = nil_t + , typename N = nil_t + , typename O = nil_t + +#endif +#endif +#endif +#endif + + , typename NU = nil_t // Not used +> +struct bound_member_action; + +////////////////////////////////// +template < + typename RT, + typename ClassT + , typename A = nil_t + , typename B = nil_t + , typename C = nil_t + +#if PHOENIX_LIMIT > 3 + , typename D = nil_t + , typename E = nil_t + , typename F = nil_t + +#if PHOENIX_LIMIT > 6 + , typename G = nil_t + , typename H = nil_t + , typename I = nil_t + +#if PHOENIX_LIMIT > 9 + , typename J = nil_t + , typename K = nil_t + , typename L = nil_t + +#if PHOENIX_LIMIT > 12 + , typename M = nil_t + , typename N = nil_t + , typename O = nil_t + +#endif +#endif +#endif +#endif +> +struct bound_member +: public function<bound_member_action<RT, ClassT + , A, B, C +#if PHOENIX_LIMIT > 3 + , D, E, F +#if PHOENIX_LIMIT > 6 + , G, H, I +#if PHOENIX_LIMIT > 9 + , J, K, L +#if PHOENIX_LIMIT > 12 + , M, N, O +#endif +#endif +#endif +#endif + > > { + + typedef bound_member_action<RT, ClassT + , A, B, C +#if PHOENIX_LIMIT > 3 + , D, E, F +#if PHOENIX_LIMIT > 6 + , G, H, I +#if PHOENIX_LIMIT > 9 + , J, K, L +#if PHOENIX_LIMIT > 12 + , M, N, O +#endif +#endif +#endif +#endif + > action_t; + + template <typename CT, typename FPT> + bound_member(CT & c, FPT fp) + : function<action_t>(action_t(c,fp)) {} + +#if !defined(__BORLANDC__) + template <typename CT, typename FPT> + bound_member(CT * c, FPT fp) + : function<action_t>(action_t(c,fp)) {} +#endif +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// Bound member function binder (specialization for 0 arg) +// +/////////////////////////////////////////////////////////////////////////////// + +template <typename RT, typename ClassT> +struct bound_member_action<RT, ClassT, + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 3 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 6 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif +#endif +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(ClassT::*mf)(); + typedef RT(ClassT::*cmf)() const; + typedef typename boost::mpl::if_<boost::is_const<ClassT>, cmf, mf>::type + mem_func_ptr_t; + + template <typename CT> + struct result { typedef result_type type; }; + + template <typename CT> + bound_member_action(CT & obj_, mem_func_ptr_t fptr_) + : obj(impl::as_ptr<CT>::get(obj_)), fptr(fptr_) {} + + result_type operator()() const + { return (obj->*fptr)(); } + + typename impl::as_ptr<ClassT>::pointer_type obj; + mem_func_ptr_t fptr; +}; + +////////////////////////////////// + +template <typename RT, typename ClassT> +inline bound_member<RT,ClassT> +bind(ClassT & obj, RT(ClassT::*fptr)()) +{ + return bound_member<RT,ClassT>(obj, fptr); +} + +template <typename RT, typename ClassT> +inline bound_member<RT,ClassT> +bind(ClassT * obj, RT(ClassT::*fptr)()) +{ +#if defined(__MWERKS__) && (__MWERKS__ < 0x3003) + return bound_member<RT,ClassT>(*obj, fptr); +#else + return bound_member<RT,ClassT>(obj, fptr); +#endif +} + +template <typename RT, typename ClassT> +inline bound_member<RT,ClassT const> +bind(ClassT const& obj, RT(ClassT::*fptr)()) +{ + return bound_member<RT,ClassT const>(obj, fptr); +} + +template <typename RT, typename ClassT> +inline bound_member<RT,ClassT const> +bind(ClassT const* obj, RT(ClassT::*fptr)() const) +{ +#if defined(__MWERKS__) && (__MWERKS__ < 0x3003) + return bound_member<RT,ClassT const>(*obj, fptr); +#else + return bound_member<RT,ClassT const>(obj, fptr); +#endif +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Bound member function binder (specialization for 1 arg) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, typename ClassT, typename A> +struct bound_member_action<RT, ClassT, + A, nil_t, nil_t, +#if PHOENIX_LIMIT > 3 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 6 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif +#endif +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(ClassT::*mf)(A); + typedef RT(ClassT::*cmf)(A) const; + typedef typename boost::mpl::if_<boost::is_const<ClassT>, cmf, mf>::type + mem_func_ptr_t; + + template <typename A_> + struct result { typedef result_type type; }; + + template <typename CT> + bound_member_action(CT & obj_, mem_func_ptr_t fptr_) + : obj(impl::as_ptr<CT>::get(obj_)), fptr(fptr_) {} + + result_type operator()(A a) const + { return (obj->*fptr)(a); } + + typename impl::as_ptr<ClassT>::pointer_type obj; + mem_func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, typename ClassT, typename A> +inline bound_member<RT, ClassT, A> +bind(ClassT & obj, RT(ClassT::*fptr)(A)) +{ + return bound_member<RT, ClassT, A>(obj,fptr); +} + +template <typename RT, typename ClassT, typename A> +inline bound_member<RT, ClassT, A> +bind(ClassT * obj, RT(ClassT::*fptr)(A)) +{ + return bound_member<RT, ClassT, A>(obj,fptr); +} + +////////////////////////////////// +template <typename RT, typename ClassT, typename A> +inline bound_member<RT, ClassT const, A> +bind(ClassT const& obj, RT(ClassT::*fptr)(A) const) +{ + return bound_member<RT, ClassT const, A>(obj,fptr); +} + +template <typename RT, typename ClassT, typename A> +inline bound_member<RT, ClassT const, A> +bind(ClassT const* obj, RT(ClassT::*fptr)(A) const) +{ + return bound_member<RT, ClassT const, A>(obj,fptr); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Bound member function binder (specialization for 2 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, typename ClassT, typename A, typename B> +struct bound_member_action<RT, ClassT, + A, B, nil_t, +#if PHOENIX_LIMIT > 3 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 6 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif +#endif +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(ClassT::*mf)(A, B); + typedef RT(ClassT::*cmf)(A, B) const; + typedef typename boost::mpl::if_<boost::is_const<ClassT>, cmf, mf>::type + mem_func_ptr_t; + + template <typename A_, typename B_> + struct result { typedef result_type type; }; + + template <typename CT> + bound_member_action(CT & obj_, mem_func_ptr_t fptr_) + : obj(impl::as_ptr<CT>::get(obj_)), fptr(fptr_) {} + + result_type operator()(A a, B b) const + { return (obj->*fptr)(a, b); } + + typename impl::as_ptr<ClassT>::pointer_type obj; + mem_func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, typename ClassT, typename A, typename B> +inline bound_member<RT, ClassT, A, B> +bind(ClassT & obj,RT(ClassT::*fptr)(A, B)) +{ + return bound_member<RT, ClassT, A, B>(obj,fptr); +} + +template <typename RT, typename ClassT, typename A, typename B> +inline bound_member<RT, ClassT, A, B> +bind(ClassT * obj,RT(ClassT::*fptr)(A, B)) +{ + return bound_member<RT, ClassT, A, B>(obj,fptr); +} + +template <typename RT, typename ClassT, typename A, typename B> +inline bound_member<RT, ClassT const, A, B> +bind(ClassT const& obj,RT(ClassT::*fptr)(A, B) const) +{ + return bound_member<RT, ClassT const, A, B>(obj,fptr); +} + +template <typename RT, typename ClassT, typename A, typename B> +inline bound_member<RT, ClassT const, A, B> +bind(ClassT const* obj,RT(ClassT::*fptr)(A, B) const) +{ + return bound_member<RT, ClassT const, A, B>(obj,fptr); +} + +#if PHOENIX_LIMIT > 3 +/////////////////////////////////////////////////////////////////////////////// +// +// Bound member function binder (specialization for 3 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, typename ClassT, typename A, typename B, typename C> +struct bound_member_action<RT, ClassT, + A, B, C, nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 6 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(ClassT::*mf)(A, B, C); + typedef RT(ClassT::*cmf)(A, B, C) const; + typedef typename boost::mpl::if_<boost::is_const<ClassT>, cmf, mf>::type + mem_func_ptr_t; + + template <typename A_, typename B_, typename C_> + struct result { typedef result_type type; }; + + template <typename CT> + bound_member_action(CT & obj_, mem_func_ptr_t fptr_) + : obj(impl::as_ptr<CT>::get(obj_)), fptr(fptr_) {} + + result_type operator()(A a, B b, C c) const + { return (obj->*fptr)(a, b, c); } + + typename impl::as_ptr<ClassT>::pointer_type obj; + mem_func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, typename ClassT, typename A, typename B, typename C> +inline bound_member<RT, ClassT, A, B, C> +bind(ClassT & obj,RT(ClassT::*fptr)(A, B, C)) +{ + return bound_member<RT, ClassT, A, B, C>(obj,fptr); +} + +template <typename RT, typename ClassT, typename A, typename B, typename C> +inline bound_member<RT, ClassT, A, B, C> +bind(ClassT * obj,RT(ClassT::*fptr)(A, B, C)) +{ + return bound_member<RT, ClassT, A, B, C>(obj,fptr); +} + +template <typename RT, typename ClassT, typename A, typename B, typename C> +inline bound_member<RT, ClassT const, A, B, C> +bind(ClassT const& obj,RT(ClassT::*fptr)(A, B, C) const) +{ + return bound_member<RT, ClassT const, A, B, C>(obj,fptr); +} + +template <typename RT, typename ClassT, typename A, typename B, typename C> +inline bound_member<RT, ClassT const, A, B, C> +bind(ClassT const* obj,RT(ClassT::*fptr)(A, B, C) const) +{ + return bound_member<RT, ClassT const, A, B, C>(obj,fptr); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Bound member function binder (specialization for 4 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D +> +struct bound_member_action<RT, ClassT, + A, B, C, D, nil_t, nil_t, +#if PHOENIX_LIMIT > 6 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(ClassT::*mf)(A, B, C, D); + typedef RT(ClassT::*cmf)(A, B, C, D) const; + typedef typename boost::mpl::if_<boost::is_const<ClassT>, cmf, mf>::type + mem_func_ptr_t; + + template <typename A_, typename B_, typename C_, typename D_> + struct result { typedef result_type type; }; + + template <typename CT> + bound_member_action(CT & obj_, mem_func_ptr_t fptr_) + : obj(impl::as_ptr<CT>::get(obj_)), fptr(fptr_) {} + + result_type operator()(A a, B b, C c, D d) const + { return (obj->*fptr)(a, b, c, d); } + + typename impl::as_ptr<ClassT>::pointer_type obj; + mem_func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D +> +inline bound_member<RT, ClassT, A, B, C, D> +bind(ClassT & obj,RT(ClassT::*fptr)(A, B, C, D)) +{ + return bound_member< + RT, ClassT, A, B, C, D>(obj,fptr); +} + +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D +> +inline bound_member<RT, ClassT, A, B, C, D> +bind(ClassT * obj,RT(ClassT::*fptr)(A, B, C, D)) +{ + return bound_member< + RT, ClassT, A, B, C, D>(obj,fptr); +} + +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D +> +inline bound_member<RT, ClassT const, A, B, C, D> +bind(ClassT const& obj,RT(ClassT::*fptr)(A, B, C, D) const) +{ + return bound_member< + RT, ClassT const, A, B, C, D>(obj,fptr); +} + +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D +> +inline bound_member<RT, ClassT const, A, B, C, D> +bind(ClassT const* obj,RT(ClassT::*fptr)(A, B, C, D) const) +{ + return bound_member< + RT, ClassT const, A, B, C, D>(obj,fptr); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Bound member function binder (specialization for 5 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E +> +struct bound_member_action<RT, ClassT, + A, B, C, D, E, nil_t, +#if PHOENIX_LIMIT > 6 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(ClassT::*mf)(A, B, C, D, E); + typedef RT(ClassT::*cmf)(A, B, C, D, E) const; + typedef typename boost::mpl::if_<boost::is_const<ClassT>, cmf, mf>::type + mem_func_ptr_t; + + template <typename A_, typename B_, typename C_, typename D_, + typename E_ + > + struct result { typedef result_type type; }; + + template <typename CT> + bound_member_action(CT & obj_, mem_func_ptr_t fptr_) + : obj(impl::as_ptr<CT>::get(obj_)), fptr(fptr_) {} + + result_type operator()( + A a, B b, C c, D d, E e + ) const + { return (obj->*fptr)(a, b, c, d, e); } + + typename impl::as_ptr<ClassT>::pointer_type obj; + mem_func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E +> +inline bound_member<RT, ClassT, A, B, C, D, E> +bind(ClassT & obj,RT(ClassT::*fptr)(A, B, C, D, E)) +{ + return bound_member< + RT, ClassT, A, B, C, D, E>(obj,fptr); +} + +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E +> +inline bound_member<RT, ClassT, A, B, C, D, E> +bind(ClassT * obj,RT(ClassT::*fptr)(A, B, C, D, E)) +{ + return bound_member< + RT, ClassT, A, B, C, D, E>(obj,fptr); +} + +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E +> +inline bound_member<RT, ClassT const, A, B, C, D, E> +bind(ClassT const& obj,RT(ClassT::*fptr)(A, B, C, D, E) const) +{ + return bound_member< + RT, ClassT const, A, B, C, D, E>(obj,fptr); +} + +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E +> +inline bound_member<RT, ClassT const, A, B, C, D, E> +bind(ClassT const* obj,RT(ClassT::*fptr)(A, B, C, D, E) const) +{ + return bound_member< + RT, ClassT const, A, B, C, D, E>(obj,fptr); +} + +#if PHOENIX_LIMIT > 6 +/////////////////////////////////////////////////////////////////////////////// +// +// Bound member function binder (specialization for 6 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F +> +struct bound_member_action<RT, ClassT, + A, B, C, D, E, F, nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(ClassT::*mf)(A, B, C, D, E, F); + typedef RT(ClassT::*cmf)(A, B, C, D, E, F) const; + typedef typename boost::mpl::if_<boost::is_const<ClassT>, cmf, mf>::type + mem_func_ptr_t; + + template < + typename A_, typename B_, typename C_, typename D_, + typename E_, typename F_ + > + struct result { typedef result_type type; }; + + template <typename CT> + bound_member_action(CT & obj_, mem_func_ptr_t fptr_) + : obj(impl::as_ptr<CT>::get(obj_)), fptr(fptr_) {} + + result_type operator()( + A a, B b, C c, D d, E e, F f + ) const + { return (obj->*fptr)(a, b, c, d, e, f); } + + typename impl::as_ptr<ClassT>::pointer_type obj; + mem_func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F +> +inline bound_member<RT, ClassT, A, B, C, D, E, F> +bind(ClassT & obj,RT(ClassT::*fptr)(A, B, C, D, E, F)) +{ + return bound_member< + RT, ClassT, A, B, C, D, E, F>(obj,fptr); +} + +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F +> +inline bound_member<RT, ClassT, A, B, C, D, E, F> +bind(ClassT * obj,RT(ClassT::*fptr)(A, B, C, D, E, F)) +{ + return bound_member< + RT, ClassT, A, B, C, D, E, F>(obj,fptr); +} + +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F +> +inline bound_member<RT, ClassT const, A, B, C, D, E, F> +bind(ClassT const& obj,RT(ClassT::*fptr)(A, B, C, D, E, F) const) +{ + return bound_member< + RT, ClassT const, A, B, C, D, E, F>(obj,fptr); +} + +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F +> +inline bound_member<RT, ClassT const, A, B, C, D, E, F> +bind(ClassT const* obj,RT(ClassT::*fptr)(A, B, C, D, E, F) const) +{ + return bound_member< + RT, ClassT const, A, B, C, D, E, F>(obj,fptr); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Bound member function binder (specialization for 7 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G +> +struct bound_member_action<RT, ClassT, + A, B, C, D, E, F, G, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(ClassT::*mf)(A, B, C, D, E, F, G); + typedef RT(ClassT::*cmf)(A, B, C, D, E, F, G) const; + typedef typename boost::mpl::if_<boost::is_const<ClassT>, cmf, mf>::type + mem_func_ptr_t; + + template < + typename A_, typename B_, typename C_, typename D_, + typename E_, typename F_, typename G_ + > + struct result { typedef result_type type; }; + + template <typename CT> + bound_member_action(CT & obj_, mem_func_ptr_t fptr_) + : obj(impl::as_ptr<CT>::get(obj_)), fptr(fptr_) {} + + result_type operator()( + A a, B b, C c, D d, E e, F f, G g + ) const + { return (obj->*fptr)(a, b, c, d, e, f, g); } + + typename impl::as_ptr<ClassT>::pointer_type obj; + mem_func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G +> +inline bound_member<RT, ClassT, A, B, C, D, E, F, G> +bind(ClassT & obj,RT(ClassT::*fptr)(A, B, C, D, E, F, G)) +{ + return bound_member< + RT, ClassT, A, B, C, D, E, F, G>(obj,fptr); +} + +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G +> +inline bound_member<RT, ClassT, A, B, C, D, E, F, G> +bind(ClassT * obj,RT(ClassT::*fptr)(A, B, C, D, E, F, G)) +{ + return bound_member< + RT, ClassT, A, B, C, D, E, F, G>(obj,fptr); +} + +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G +> +inline bound_member<RT, ClassT const, A, B, C, D, E, F, G> +bind(ClassT const& obj,RT(ClassT::*fptr)(A, B, C, D, E, F, G) const) +{ + return bound_member< + RT, ClassT const, A, B, C, D, E, F, G>(obj,fptr); +} + +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G +> +inline bound_member<RT, ClassT const, A, B, C, D, E, F, G> +bind(ClassT const* obj,RT(ClassT::*fptr)(A, B, C, D, E, F, G) const) +{ + return bound_member< + RT, ClassT const, A, B, C, D, E, F, G>(obj,fptr); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Bound member function binder (specialization for 8 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H +> +struct bound_member_action<RT, ClassT, + A, B, C, D, E, F, G, H, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(ClassT::*mf)(A, B, C, D, E, F, G, H); + typedef RT(ClassT::*cmf)(A, B, C, D, E, F, G, H) const; + typedef typename boost::mpl::if_<boost::is_const<ClassT>, cmf, mf>::type + mem_func_ptr_t; + + template < + typename A_, typename B_, typename C_, typename D_, + typename E_, typename F_, typename G_, typename H_ + > + struct result { typedef result_type type; }; + + template <typename CT> + bound_member_action(CT & obj_, mem_func_ptr_t fptr_) + : obj(impl::as_ptr<CT>::get(obj_)), fptr(fptr_) {} + + result_type operator()( + A a, B b, C c, D d, E e, F f, G g, H h + ) const + { return (obj->*fptr)(a, b, c, d, e, f, g, h); } + + typename impl::as_ptr<ClassT>::pointer_type obj; + mem_func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H +> +inline bound_member<RT, ClassT, A, B, C, D, E, F, G, H> +bind(ClassT & obj,RT(ClassT::*fptr)(A, B, C, D, E, F, G, H)) +{ + return bound_member< + RT, ClassT, A, B, C, D, E, F, G, H>(obj,fptr); +} + +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H +> +inline bound_member<RT, ClassT, A, B, C, D, E, F, G, H> +bind(ClassT * obj,RT(ClassT::*fptr)(A, B, C, D, E, F, G, H)) +{ + return bound_member< + RT, ClassT, A, B, C, D, E, F, G, H>(obj,fptr); +} + +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H +> +inline bound_member<RT, ClassT const, A, B, C, D, E, F, G, H> +bind(ClassT const& obj,RT(ClassT::*fptr)(A, B, C, D, E, F, G, H) const) +{ + return bound_member< + RT, ClassT const, A, B, C, D, E, F, G, H>(obj,fptr); +} + +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H +> +inline bound_member<RT, ClassT const, A, B, C, D, E, F, G, H> +bind(ClassT const* obj,RT(ClassT::*fptr)(A, B, C, D, E, F, G, H) const) +{ + return bound_member< + RT, ClassT const, A, B, C, D, E, F, G, H>(obj,fptr); +} + +#if PHOENIX_LIMIT > 9 +/////////////////////////////////////////////////////////////////////////////// +// +// Bound member function binder (specialization for 9 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I +> +struct bound_member_action<RT, ClassT, + A, B, C, D, E, F, G, H, I, nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(ClassT::*mf)(A, B, C, D, E, F, G, H, I); + typedef RT(ClassT::*cmf)(A, B, C, D, E, F, G, H, I) const; + typedef typename boost::mpl::if_<boost::is_const<ClassT>, cmf, mf>::type + mem_func_ptr_t; + + template < + typename A_, typename B_, typename C_, typename D_, + typename E_, typename F_, typename G_, typename H_, typename I_ + > + struct result { typedef result_type type; }; + + template <typename CT> + bound_member_action(CT & obj_, mem_func_ptr_t fptr_) + : obj(impl::as_ptr<CT>::get(obj_)), fptr(fptr_) {} + + result_type operator()( + A a, B b, C c, D d, E e, F f, G g, H h, I i + ) const + { return (obj->*fptr)(a, b, c, d, e, f, g, h, i); } + + typename impl::as_ptr<ClassT>::pointer_type obj; + mem_func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I +> +inline bound_member<RT, ClassT, A, B, C, D, E, F, G, H, I> +bind(ClassT & obj,RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I)) +{ + return bound_member< + RT, ClassT, A, B, C, D, E, F, G, H, I>(obj,fptr); +} + +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I +> +inline bound_member<RT, ClassT, A, B, C, D, E, F, G, H, I> +bind(ClassT * obj,RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I)) +{ + return bound_member< + RT, ClassT, A, B, C, D, E, F, G, H, I>(obj,fptr); +} + +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I +> +inline bound_member<RT, ClassT const, A, B, C, D, E, F, G, H, I> +bind(ClassT const& obj,RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I) const) +{ + return bound_member< + RT, ClassT const, A, B, C, D, E, F, G, H, I>(obj,fptr); +} + +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I +> +inline bound_member<RT, ClassT const, A, B, C, D, E, F, G, H, I> +bind(ClassT const* obj,RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I) const) +{ + return bound_member< + RT, ClassT const, A, B, C, D, E, F, G, H, I>(obj,fptr); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Bound member function binder (specialization for 10 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J +> +struct bound_member_action<RT, ClassT, + A, B, C, D, E, F, G, H, I, J, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(ClassT::*mf)(A, B, C, D, E, F, G, H, I, J); + typedef RT(ClassT::*cmf)(A, B, C, D, E, F, G, H, I, J) const; + typedef typename boost::mpl::if_<boost::is_const<ClassT>, cmf, mf>::type + mem_func_ptr_t; + + template < + typename A_, typename B_, typename C_, typename D_, + typename E_, typename F_, typename G_, typename H_, typename I_, + typename J_ + > + struct result { typedef result_type type; }; + + template <typename CT> + bound_member_action(CT & obj_, mem_func_ptr_t fptr_) + : obj(impl::as_ptr<CT>::get(obj_)), fptr(fptr_) {} + + result_type operator()( + A a, B b, C c, D d, E e, F f, G g, H h, I i, J j + ) const + { + return (obj->*fptr)(a, b, c, d, e, f, g, h, i, j); + } + + typename impl::as_ptr<ClassT>::pointer_type obj; + mem_func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J +> +inline bound_member<RT, ClassT, A, B, C, D, E, F, G, H, I, J> +bind(ClassT & obj,RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I, J)) +{ + return bound_member< + RT, ClassT, A, B, C, D, E, F, G, H, I, J>(obj,fptr); +} + +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J +> +inline bound_member<RT, ClassT, A, B, C, D, E, F, G, H, I, J> +bind(ClassT * obj,RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I, J)) +{ + return bound_member< + RT, ClassT, A, B, C, D, E, F, G, H, I, J>(obj,fptr); +} + +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J +> +inline bound_member<RT, ClassT const, A, B, C, D, E, F, G, H, I, J> +bind(ClassT const& obj,RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I, J) const) +{ + return bound_member< + RT, ClassT const, A, B, C, D, E, F, G, H, I, J>(obj,fptr); +} + +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J +> +inline bound_member<RT, ClassT const, A, B, C, D, E, F, G, H, I, J> +bind(ClassT const* obj,RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I, J) const) +{ + return bound_member< + RT, ClassT const, A, B, C, D, E, F, G, H, I, J>(obj,fptr); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Bound member function binder (specialization for 11 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K +> +struct bound_member_action<RT, ClassT, + A, B, C, D, E, F, G, H, I, J, K, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif + nil_t // Unused +> { + + typedef RT result_type; + typedef RT(ClassT::*mf)(A, B, C, D, E, F, G, H, I, J, K); + typedef RT(ClassT::*cmf)(A, B, C, D, E, F, G, H, I, J, K) const; + typedef typename boost::mpl::if_<boost::is_const<ClassT>, cmf, mf>::type + mem_func_ptr_t; + + template < + typename A_, typename B_, typename C_, typename D_, + typename E_, typename F_, typename G_, typename H_, typename I_, + typename J_, typename K_ + > + struct result { typedef result_type type; }; + + template <typename CT> + bound_member_action(CT & obj_, mem_func_ptr_t fptr_) + : obj(impl::as_ptr<CT>::get(obj_)), fptr(fptr_) {} + + result_type operator()( + A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k + ) const + { + return (obj->*fptr)(a, b, c, d, e, f, g, h, i, j, k); + } + + typename impl::as_ptr<ClassT>::pointer_type obj; + mem_func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K +> +inline bound_member<RT, ClassT, A, B, C, D, E, F, G, H, I, J, K> +bind(ClassT & obj,RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I, J, K)) +{ + return bound_member< + RT, ClassT, A, B, C, D, E, F, G, H, I, J, K>(obj,fptr); +} + +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K +> +inline bound_member<RT, ClassT, A, B, C, D, E, F, G, H, I, J, K> +bind(ClassT * obj,RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I, J, K)) +{ + return bound_member< + RT, ClassT, A, B, C, D, E, F, G, H, I, J, K>(obj,fptr); +} + +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K +> +inline bound_member<RT, ClassT const, A, B, C, D, E, F, G, H, I, J, K> +bind(ClassT const& obj,RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I, J, K) const) +{ + return bound_member< + RT, ClassT const, A, B, C, D, E, F, G, H, I, J, K>(obj,fptr); +} + +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K +> +inline bound_member<RT, ClassT const, A, B, C, D, E, F, G, H, I, J, K> +bind(ClassT const* obj,RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I, J, K) const) +{ + return bound_member< + RT, ClassT const, A, B, C, D, E, F, G, H, I, J, K>(obj,fptr); +} + +#if PHOENIX_LIMIT > 12 +/////////////////////////////////////////////////////////////////////////////// +// +// Bound member function binder (specialization for 12 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K, typename L +> +struct bound_member_action<RT, ClassT, + A, B, C, D, E, F, G, H, I, J, K, L, nil_t, nil_t, nil_t, nil_t> { + + typedef RT result_type; + typedef RT(ClassT::*mf)(A, B, C, D, E, F, G, H, I, J, K, L); + typedef RT(ClassT::*cmf)(A, B, C, D, E, F, G, H, I, J, K, L) const; + typedef typename boost::mpl::if_<boost::is_const<ClassT>, cmf, mf>::type + mem_func_ptr_t; + + template < + typename A_, typename B_, typename C_, typename D_, + typename E_, typename F_, typename G_, typename H_, typename I_, + typename J_, typename K_, typename L_ + > + struct result { typedef result_type type; }; + + template <typename CT> + bound_member_action(CT & obj_, mem_func_ptr_t fptr_) + : obj(impl::as_ptr<CT>::get(obj_)), fptr(fptr_) {} + + result_type operator()( + A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l + ) const + { + return (obj->*fptr)(a, b, c, d, e, f, g, h, i, j, k, l); + } + + typename impl::as_ptr<ClassT>::pointer_type obj; + mem_func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K, typename L +> +inline bound_member<RT, ClassT, A, B, C, D, E, F, G, H, I, J, K, L> +bind(ClassT & obj,RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I, J, K, L)) +{ + return bound_member< + RT, ClassT, A, B, C, D, E, F, G, H, I, J, K, L>(obj,fptr); +} + +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K, typename L +> +inline bound_member<RT, ClassT, A, B, C, D, E, F, G, H, I, J, K, L> +bind(ClassT * obj,RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I, J, K, L)) +{ + return bound_member< + RT, ClassT, A, B, C, D, E, F, G, H, I, J, K, L>(obj,fptr); +} + +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K, typename L +> +inline bound_member<RT, ClassT const, A, B, C, D, E, F, G, H, I, J, K, L> +bind(ClassT const& obj,RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I, J, K, L) const) +{ + return bound_member< + RT, ClassT const, A, B, C, D, E, F, G, H, I, J, K, L>(obj,fptr); +} + +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K, typename L +> +inline bound_member<RT, ClassT const, A, B, C, D, E, F, G, H, I, J, K, L> +bind(ClassT const* obj,RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I, J, K, L) const) +{ + return bound_member< + RT, ClassT const, A, B, C, D, E, F, G, H, I, J, K, L>(obj,fptr); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Bound member function binder (specialization for 13 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K, typename L, typename M +> +struct bound_member_action<RT, ClassT, + A, B, C, D, E, F, G, H, I, J, K, L, M, nil_t, nil_t, nil_t> { + + typedef RT result_type; + typedef RT(ClassT::*mf)(A, B, C, D, E, F, G, H, I, J, K, L, M); + typedef RT(ClassT::*cmf)(A, B, C, D, E, F, G, H, I, J, K, L, M) const; + typedef typename boost::mpl::if_<boost::is_const<ClassT>, cmf, mf>::type + mem_func_ptr_t; + + template < + typename A_, typename B_, typename C_, typename D_, + typename E_, typename F_, typename G_, typename H_, typename I_, + typename J_, typename K_, typename L_, typename M_ + > + struct result { typedef result_type type; }; + + template <typename CT> + bound_member_action(CT & obj_, mem_func_ptr_t fptr_) + : obj(impl::as_ptr<CT>::get(obj_)), fptr(fptr_) {} + + result_type operator()( + A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, M m + ) const + { + return (obj->*fptr)(a, b, c, d, e, f, g, h, i, j, k, l, m); + } + + typename impl::as_ptr<ClassT>::pointer_type obj; + mem_func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K, typename L, typename M +> +inline bound_member<RT, ClassT, A, B, C, D, E, F, G, H, I, J, K, L, M> +bind(ClassT & obj,RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I, J, K, L, M)) +{ + return bound_member< + RT, ClassT, A, B, C, D, E, F, G, H, I, J, K, L, M>(obj,fptr); +} + +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K, typename L, typename M +> +inline bound_member<RT, ClassT, A, B, C, D, E, F, G, H, I, J, K, L, M> +bind(ClassT * obj,RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I, J, K, L, M)) +{ + return bound_member< + RT, ClassT, A, B, C, D, E, F, G, H, I, J, K, L, M>(obj,fptr); +} + +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K, typename L, typename M +> +inline bound_member<RT, ClassT const, A, B, C, D, E, F, G, H, I, J, K, L, M> +bind(ClassT const& obj,RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I, J, K, L, M) const) +{ + return bound_member< + RT, ClassT const, A, B, C, D, E, F, G, H, I, J, K, L, M>(obj,fptr); +} + +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K, typename L, typename M +> +inline bound_member<RT, ClassT const, A, B, C, D, E, F, G, H, I, J, K, L, M> +bind(ClassT const* obj,RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I, J, K, L, M) const) +{ + return bound_member< + RT, ClassT const, A, B, C, D, E, F, G, H, I, J, K, L, M>(obj,fptr); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Bound member function binder (specialization for 14 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K, typename L, typename M, typename N +> +struct bound_member_action<RT, ClassT, + A, B, C, D, E, F, G, H, I, J, K, L, M, N, nil_t, nil_t> { + + typedef RT result_type; + typedef RT(ClassT::*mf)(A, B, C, D, E, F, G, H, I, J, K, L, M, N); + typedef RT(ClassT::*cmf)(A, B, C, D, E, F, G, H, I, J, K, L, M, N) const; + typedef typename boost::mpl::if_<boost::is_const<ClassT>, cmf, mf>::type + mem_func_ptr_t; + + template < + typename A_, typename B_, typename C_, typename D_, + typename E_, typename F_, typename G_, typename H_, typename I_, + typename J_, typename K_, typename L_, typename M_, typename N_ + > + struct result { typedef result_type type; }; + + template <typename CT> + bound_member_action(CT & obj_, mem_func_ptr_t fptr_) + : obj(impl::as_ptr<CT>::get(obj_)), fptr(fptr_) {} + + result_type operator()( + A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, M m, N n + ) const + { + return (obj->*fptr)(a, b, c, d, e, f, g, h, i, j, k, l, m, n); + } + + typename impl::as_ptr<ClassT>::pointer_type obj; + mem_func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K, typename L, typename M, typename N +> +inline bound_member<RT, ClassT, A, B, C, D, E, F, G, H, I, J, K, L, M, N> +bind(ClassT & obj,RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I, J, K, L, M, N)) +{ + return bound_member< + RT, ClassT, A, B, C, D, E, F, G, H, I, J, K, L, M, N>(obj,fptr); +} + +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K, typename L, typename M, typename N +> +inline bound_member<RT, ClassT, A, B, C, D, E, F, G, H, I, J, K, L, M, N> +bind(ClassT * obj,RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I, J, K, L, M, N)) +{ + return bound_member< + RT, ClassT, A, B, C, D, E, F, G, H, I, J, K, L, M, N>(obj,fptr); +} + +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K, typename L, typename M, typename N +> +inline bound_member<RT, ClassT const, A, B, C, D, E, F, G, H, I, J, K, L, M, N> +bind(ClassT const& obj,RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I, J, K, L, M, N) const) +{ + return bound_member< + RT, ClassT const, A, B, C, D, E, F, G, H, I, J, K, L, M, N>(obj,fptr); +} + +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K, typename L, typename M, typename N +> +inline bound_member<RT, ClassT const, A, B, C, D, E, F, G, H, I, J, K, L, M, N> +bind(ClassT const* obj,RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I, J, K, L, M, N) const) +{ + return bound_member< + RT, ClassT const, A, B, C, D, E, F, G, H, I, J, K, L, M, N>(obj,fptr); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Bound member function binder (specialization for 15 args) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K, typename L, typename M, typename N, + typename O +> +struct bound_member_action<RT, ClassT, + A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, nil_t> { + + typedef RT result_type; + typedef RT(ClassT::*mf)(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O); + typedef RT(ClassT::*cmf)(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O) const; + typedef typename boost::mpl::if_<boost::is_const<ClassT>, cmf, mf>::type + mem_func_ptr_t; + + template < + typename A_, typename B_, typename C_, typename D_, + typename E_, typename F_, typename G_, typename H_, typename I_, + typename J_, typename K_, typename L_, typename M_, typename N_, + typename O_ + > + struct result { typedef result_type type; }; + + template <typename CT> + bound_member_action(CT & obj_, mem_func_ptr_t fptr_) + : obj(impl::as_ptr<CT>::get(obj_)), fptr(fptr_) {} + + result_type operator()( + A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, M m, N n, O o + ) const + { + return (obj->*fptr)(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o); + } + + typename impl::as_ptr<ClassT>::pointer_type obj; + mem_func_ptr_t fptr; +}; + +////////////////////////////////// +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K, typename L, typename M, typename N, + typename O +> +inline bound_member<RT, ClassT, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O> +bind(ClassT & obj,RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O)) +{ + return bound_member< + RT, ClassT, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O>(obj,fptr); +} + +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K, typename L, typename M, typename N, + typename O +> +inline bound_member<RT, ClassT, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O> +bind(ClassT * obj,RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O)) +{ + return bound_member< + RT, ClassT, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O>(obj,fptr); +} + +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K, typename L, typename M, typename N, + typename O +> +inline bound_member<RT, ClassT const, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O> +bind(ClassT const& obj,RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O) const) +{ + return bound_member< + RT, ClassT const, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O>(obj,fptr); +} + +template <typename RT, typename ClassT, + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, typename I, + typename J, typename K, typename L, typename M, typename N, + typename O +> +inline bound_member<RT, ClassT const, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O> +bind(ClassT const* obj,RT(ClassT::*fptr)(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O) const) +{ + return bound_member< + RT, ClassT const, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O>(obj,fptr); +} + +#endif +#endif +#endif +#endif + +} // namespace phoenix + +#endif diff --git a/boost/spirit/home/classic/phoenix/casts.hpp b/boost/spirit/home/classic/phoenix/casts.hpp new file mode 100644 index 0000000000..84922a7608 --- /dev/null +++ b/boost/spirit/home/classic/phoenix/casts.hpp @@ -0,0 +1,1470 @@ +/*============================================================================= + Phoenix V1.2.1 + Copyright (c) 2001-2003 Joel de Guzman + Copyright (c) 2001-2003 Hartmut Kaiser + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#ifndef PHOENIX_CASTS_HPP +#define PHOENIX_CASTS_HPP + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/spirit/home/classic/phoenix/actor.hpp> +#include <boost/spirit/home/classic/phoenix/composite.hpp> +#include <boost/static_assert.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace phoenix { + +/////////////////////////////////////////////////////////////////////////////// +// +// Phoenix predefined maximum construct_ limit. This limit defines the maximum +// number of parameters supported for calles to the set of construct_ template +// functions (lazy object construction, see below). This number defaults to 3. +// The actual maximum is rounded up in multiples of 3. Thus, if this value +// is 4, the actual limit is 6. The ultimate maximum limit in this +// implementation is 15. +// PHOENIX_CONSTRUCT_LIMIT should NOT be greater than PHOENIX_LIMIT! + +#if !defined(PHOENIX_CONSTRUCT_LIMIT) +#define PHOENIX_CONSTRUCT_LIMIT PHOENIX_LIMIT +#endif + +// ensure PHOENIX_CONSTRUCT_LIMIT <= PHOENIX_LIMIT +BOOST_STATIC_ASSERT(PHOENIX_CONSTRUCT_LIMIT <= PHOENIX_LIMIT); + +// ensure PHOENIX_CONSTRUCT_LIMIT <= 15 +BOOST_STATIC_ASSERT(PHOENIX_CONSTRUCT_LIMIT <= 15); + +/////////////////////////////////////////////////////////////////////////////// +// +// Lazy C++ casts +// +// The set of lazy C++ cast template classes and functions provide a way +// of lazily casting certain type to another during parsing. +// The lazy C++ templates are (syntactically) used very much like +// the well known C++ casts: +// +// A *a = static_cast_<A *>(...actor returning a convertible type...); +// +// where the given parameter should be an actor, which eval() function +// returns a convertible type. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename T, typename A> +struct static_cast_l { + + template <typename TupleT> + struct result { typedef T type; }; + + static_cast_l(A const& a_) + : a(a_) {} + + template <typename TupleT> + T + eval(TupleT const& args) const + { + return static_cast<T>(a.eval(args)); + } + + A a; +}; + +////////////////////////////////// +template <typename T, typename BaseAT> +inline actor<static_cast_l<T, BaseAT> > +static_cast_(actor<BaseAT> const& a) +{ + typedef static_cast_l<T, BaseAT> cast_t; + return actor<cast_t>(cast_t(a)); +} + +////////////////////////////////// +template <typename T, typename A> +struct dynamic_cast_l { + + template <typename TupleT> + struct result { typedef T type; }; + + dynamic_cast_l(A const& a_) + : a(a_) {} + + template <typename TupleT> + T + eval(TupleT const& args) const + { + return dynamic_cast<T>(a.eval(args)); + } + + A a; +}; + +////////////////////////////////// +template <typename T, typename BaseAT> +inline actor<dynamic_cast_l<T, BaseAT> > +dynamic_cast_(actor<BaseAT> const& a) +{ + typedef dynamic_cast_l<T, BaseAT> cast_t; + return actor<cast_t>(cast_t(a)); +} + +////////////////////////////////// +template <typename T, typename A> +struct reinterpret_cast_l { + + template <typename TupleT> + struct result { typedef T type; }; + + reinterpret_cast_l(A const& a_) + : a(a_) {} + + template <typename TupleT> + T + eval(TupleT const& args) const + { + return reinterpret_cast<T>(a.eval(args)); + } + + A a; +}; + +////////////////////////////////// +template <typename T, typename BaseAT> +inline actor<reinterpret_cast_l<T, BaseAT> > +reinterpret_cast_(actor<BaseAT> const& a) +{ + typedef reinterpret_cast_l<T, BaseAT> cast_t; + return actor<cast_t>(cast_t(a)); +} + +////////////////////////////////// +template <typename T, typename A> +struct const_cast_l { + + template <typename TupleT> + struct result { typedef T type; }; + + const_cast_l(A const& a_) + : a(a_) {} + + template <typename TupleT> + T + eval(TupleT const& args) const + { + return const_cast<T>(a.eval(args)); + } + + A a; +}; + +////////////////////////////////// +template <typename T, typename BaseAT> +inline actor<const_cast_l<T, BaseAT> > +const_cast_(actor<BaseAT> const& a) +{ + typedef const_cast_l<T, BaseAT> cast_t; + return actor<cast_t>(cast_t(a)); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// construct_ +// +// Lazy object construction +// +// The set of construct_<> template classes and functions provide a way +// of lazily constructing certain object from a arbitrary set of +// actors during parsing. +// The construct_ templates are (syntactically) used very much like +// the well known C++ casts: +// +// A a = construct_<A>(...arbitrary list of actors...); +// +// where the given parameters are submitted as parameters to the +// contructor of the object of type A. (This certainly implies, that +// type A has a constructor with a fitting set of parameter types +// defined.) +// +// The maximum number of needed parameters is controlled through the +// preprocessor constant PHOENIX_CONSTRUCT_LIMIT. Note though, that this +// limit should not be greater than PHOENIX_LIMIT. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename T> +struct construct_l_0 { + typedef T result_type; + + T operator()() const { + return T(); + } +}; + + +template <typename T> +struct construct_l { + + template < + typename A + , typename B + , typename C + +#if PHOENIX_CONSTRUCT_LIMIT > 3 + , typename D + , typename E + , typename F + +#if PHOENIX_CONSTRUCT_LIMIT > 6 + , typename G + , typename H + , typename I + +#if PHOENIX_CONSTRUCT_LIMIT > 9 + , typename J + , typename K + , typename L + +#if PHOENIX_CONSTRUCT_LIMIT > 12 + , typename M + , typename N + , typename O +#endif +#endif +#endif +#endif + > + struct result { typedef T type; }; + + T operator()() const + { + return T(); + } + + template <typename A> + T operator()(A const& a) const + { + T t(a); + return t; + } + + template <typename A, typename B> + T operator()(A const& a, B const& b) const + { + T t(a, b); + return t; + } + + template <typename A, typename B, typename C> + T operator()(A const& a, B const& b, C const& c) const + { + T t(a, b, c); + return t; + } + +#if PHOENIX_CONSTRUCT_LIMIT > 3 + template < + typename A, typename B, typename C, typename D + > + T operator()( + A const& a, B const& b, C const& c, D const& d) const + { + T t(a, b, c, d); + return t; + } + + template < + typename A, typename B, typename C, typename D, typename E + > + T operator()( + A const& a, B const& b, C const& c, D const& d, E const& e) const + { + T t(a, b, c, d, e); + return t; + } + + template < + typename A, typename B, typename C, typename D, typename E, + typename F + > + T operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f) const + { + T t(a, b, c, d, e, f); + return t; + } + +#if PHOENIX_CONSTRUCT_LIMIT > 6 + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G + > + T operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g) const + { + T t(a, b, c, d, e, f, g); + return t; + } + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H + > + T operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h) const + { + T t(a, b, c, d, e, f, g, h); + return t; + } + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I + > + T operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i) const + { + T t(a, b, c, d, e, f, g, h, i); + return t; + } + +#if PHOENIX_CONSTRUCT_LIMIT > 9 + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J + > + T operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j) const + { + T t(a, b, c, d, e, f, g, h, i, j); + return t; + } + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K + > + T operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k) const + { + T t(a, b, c, d, e, f, g, h, i, j, k); + return t; + } + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L + > + T operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k, L const& l) const + { + T t(a, b, c, d, e, f, g, h, i, j, k, l); + return t; + } + +#if PHOENIX_CONSTRUCT_LIMIT > 12 + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M + > + T operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k, L const& l, M const& m) const + { + T t(a, b, c, d, e, f, g, h, i, j, k, l, m); + return t; + } + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M, typename N + > + T operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k, L const& l, M const& m, N const& n) const + { + T t(a, b, c, d, e, f, g, h, i, j, k, l, m, n); + return t; + } + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M, typename N, typename O + > + T operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k, L const& l, M const& m, N const& n, O const& o) const + { + T t(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o); + return t; + } + +#endif +#endif +#endif +#endif +}; + + +template <typename T> +struct construct_1 { + + template < + typename A + > + struct result { typedef T type; }; + + template <typename A> + T operator()(A const& a) const + { + T t(a); + return t; + } + +}; + +template <typename T> +struct construct_2 { + + template < + typename A + , typename B + > + struct result { typedef T type; }; + + template <typename A, typename B> + T operator()(A const& a, B const& b) const + { + T t(a, b); + return t; + } + +}; + +template <typename T> +struct construct_3 { + + template < + typename A + , typename B + , typename C + > + struct result { typedef T type; }; + + template <typename A, typename B, typename C> + T operator()(A const& a, B const& b, C const& c) const + { + T t(a, b, c); + return t; + } +}; + +#if PHOENIX_CONSTRUCT_LIMIT > 3 +template <typename T> +struct construct_4 { + + template < + typename A + , typename B + , typename C + , typename D + > + struct result { typedef T type; }; + + template < + typename A, typename B, typename C, typename D + > + T operator()( + A const& a, B const& b, C const& c, D const& d) const + { + T t(a, b, c, d); + return t; + } +}; + + +template <typename T> +struct construct_5 { + + template < + typename A + , typename B + , typename C + , typename D + , typename E + > + struct result { typedef T type; }; + + template < + typename A, typename B, typename C, typename D, typename E + > + T operator()( + A const& a, B const& b, C const& c, D const& d, E const& e) const + { + T t(a, b, c, d, e); + return t; + } +}; + + +template <typename T> +struct construct_6 { + + template < + typename A + , typename B + , typename C + , typename D + , typename E + , typename F + > + struct result { typedef T type; }; + + template < + typename A, typename B, typename C, typename D, typename E, + typename F + > + T operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f) const + { + T t(a, b, c, d, e, f); + return t; + } +}; +#endif + + +#if PHOENIX_CONSTRUCT_LIMIT > 6 +template <typename T> +struct construct_7 { + + template < + typename A + , typename B + , typename C + , typename D + , typename E + , typename F + , typename G + > + struct result { typedef T type; }; + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G + > + T operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g) const + { + T t(a, b, c, d, e, f, g); + return t; + } +}; + +template <typename T> +struct construct_8 { + + template < + typename A + , typename B + , typename C + , typename D + , typename E + , typename F + , typename G + , typename H + > + struct result { typedef T type; }; + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H + > + T operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h) const + { + T t(a, b, c, d, e, f, g, h); + return t; + } +}; + +template <typename T> +struct construct_9 { + + template < + typename A + , typename B + , typename C + , typename D + , typename E + , typename F + , typename G + , typename H + , typename I + > + struct result { typedef T type; }; + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I + > + T operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i) const + { + T t(a, b, c, d, e, f, g, h, i); + return t; + } +}; +#endif + + +#if PHOENIX_CONSTRUCT_LIMIT > 9 +template <typename T> +struct construct_10 { + + template < + typename A + , typename B + , typename C + , typename D + , typename E + , typename F + , typename G + , typename H + , typename I + , typename J + > + struct result { typedef T type; }; + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J + > + T operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j) const + { + T t(a, b, c, d, e, f, g, h, i, j); + return t; + } +}; + +template <typename T> +struct construct_11 { + + template < + typename A + , typename B + , typename C + , typename D + , typename E + , typename F + , typename G + , typename H + , typename I + , typename J + , typename K + > + struct result { typedef T type; }; + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K + > + T operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k) const + { + T t(a, b, c, d, e, f, g, h, i, j, k); + return t; + } +}; + +template <typename T> +struct construct_12 { + + template < + typename A + , typename B + , typename C + , typename D + , typename E + , typename F + , typename G + , typename H + , typename I + , typename J + , typename K + , typename L + > + struct result { typedef T type; }; + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L + > + T operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k, L const& l) const + { + T t(a, b, c, d, f, e, g, h, i, j, k, l); + return t; + } +}; +#endif + +#if PHOENIX_CONSTRUCT_LIMIT > 12 +template <typename T> +struct construct_13 { + + template < + typename A + , typename B + , typename C + , typename D + , typename E + , typename F + , typename G + , typename H + , typename I + , typename J + , typename K + , typename L + , typename M + > + struct result { typedef T type; }; + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M + > + T operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k, L const& l, M const& m) const + { + T t(a, b, c, d, e, f, g, h, i, j, k, l, m); + return t; + } +}; + +template <typename T> +struct construct_14 { + + template < + typename A + , typename B + , typename C + , typename D + , typename E + , typename F + , typename G + , typename H + , typename I + , typename J + , typename K + , typename L + , typename M + , typename N + > + struct result { typedef T type; }; + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M, typename N + > + T operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k, L const& l, M const& m, N const& n) const + { + T t(a, b, c, d, e, f, g, h, i, j, k, l, m, n); + return t; + } +}; + +template <typename T> +struct construct_15 { + + template < + typename A + , typename B + , typename C + , typename D + , typename E + , typename F + , typename G + , typename H + , typename I + , typename J + , typename K + , typename L + , typename M + , typename N + , typename O + > + struct result { typedef T type; }; + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M, typename N, typename O + > + T operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k, L const& l, M const& m, N const& n, O const& o) const + { + T t(a, b, c, d, f, e, g, h, i, j, k, l, m, n, o); + return t; + } +}; +#endif + + +#if defined(__BORLANDC__) || (defined(__MWERKS__) && (__MWERKS__ <= 0x3002)) + +/////////////////////////////////////////////////////////////////////////////// +// +// The following specializations are needed because Borland and CodeWarrior +// does not accept default template arguments in nested template classes in +// classes (i.e construct_l::result) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename T, typename TupleT> +struct composite0_result<construct_l_0<T>, TupleT> { + + typedef T type; +}; + +////////////////////////////////// +template <typename T, typename TupleT, + typename A> +struct composite1_result<construct_l<T>, TupleT, A> { + + typedef T type; +}; + +////////////////////////////////// +template <typename T, typename TupleT, + typename A, typename B> +struct composite2_result<construct_l<T>, TupleT, A, B> { + + typedef T type; +}; + +////////////////////////////////// +template <typename T, typename TupleT, + typename A, typename B, typename C> +struct composite3_result<construct_l<T>, TupleT, A, B, C> { + + typedef T type; +}; + +#if PHOENIX_LIMIT > 3 +////////////////////////////////// +template <typename T, typename TupleT, + typename A, typename B, typename C, typename D> +struct composite4_result<construct_l<T>, TupleT, + A, B, C, D> { + + typedef T type; +}; + +////////////////////////////////// +template <typename T, typename TupleT, + typename A, typename B, typename C, typename D, typename E> +struct composite5_result<construct_l<T>, TupleT, + A, B, C, D, E> { + + typedef T type; +}; + +////////////////////////////////// +template <typename T, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F> +struct composite6_result<construct_l<T>, TupleT, + A, B, C, D, E, F> { + + typedef T type; +}; + +#if PHOENIX_LIMIT > 6 +////////////////////////////////// +template <typename T, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G> +struct composite7_result<construct_l<T>, TupleT, + A, B, C, D, E, F, G> { + + typedef T type; +}; + +////////////////////////////////// +template <typename T, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H> +struct composite8_result<construct_l<T>, TupleT, + A, B, C, D, E, F, G, H> { + + typedef T type; +}; + +////////////////////////////////// +template <typename T, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I> +struct composite9_result<construct_l<T>, TupleT, + A, B, C, D, E, F, G, H, I> { + + typedef T type; +}; + +#if PHOENIX_LIMIT > 9 +////////////////////////////////// +template <typename T, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J> +struct composite10_result<construct_l<T>, TupleT, + A, B, C, D, E, F, G, H, I, J> { + + typedef T type; +}; + +////////////////////////////////// +template <typename T, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K> +struct composite11_result<construct_l<T>, TupleT, + A, B, C, D, E, F, G, H, I, J, K> { + + typedef T type; +}; + +////////////////////////////////// +template <typename T, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L> +struct composite12_result<construct_l<T>, TupleT, + A, B, C, D, E, F, G, H, I, J, K, L> { + + typedef T type; +}; + +#if PHOENIX_LIMIT > 12 +////////////////////////////////// +template <typename T, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M> +struct composite13_result<construct_l<T>, TupleT, + A, B, C, D, E, F, G, H, I, J, K, L, M> { + + typedef T type; +}; + +////////////////////////////////// +template <typename T, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M, typename N> +struct composite14_result<construct_l<T>, TupleT, + A, B, C, D, E, F, G, H, I, J, K, L, M, N> { + + typedef T type; +}; + +////////////////////////////////// +template <typename T, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M, typename N, typename O> +struct composite15_result<construct_l<T>, TupleT, + A, B, C, D, E, F, G, H, I, J, K, L, M, N, O> { + + typedef T type; +}; + +#endif +#endif +#endif +#endif +#endif + +////////////////////////////////// +template <typename T> +inline typename impl::make_composite<construct_l_0<T> >::type +construct_() +{ + typedef impl::make_composite<construct_l_0<T> > make_composite_t; + typedef typename make_composite_t::type type_t; + typedef typename make_composite_t::composite_type composite_type_t; + + return type_t(composite_type_t(construct_l_0<T>())); +} + +////////////////////////////////// +template <typename T, typename A> +inline typename impl::make_composite<construct_1<T>, A>::type +construct_(A const& a) +{ + typedef impl::make_composite<construct_1<T>, A> make_composite_t; + typedef typename make_composite_t::type type_t; + typedef typename make_composite_t::composite_type composite_type_t; + + return type_t(composite_type_t(construct_1<T>(), + as_actor<A>::convert(a) + )); +} + +////////////////////////////////// +template <typename T, typename A, typename B> +inline typename impl::make_composite<construct_2<T>, A, B>::type +construct_(A const& a, B const& b) +{ + typedef impl::make_composite<construct_2<T>, A, B> make_composite_t; + typedef typename make_composite_t::type type_t; + typedef typename make_composite_t::composite_type composite_type_t; + + return type_t(composite_type_t(construct_2<T>(), + as_actor<A>::convert(a), + as_actor<B>::convert(b) + )); +} + +////////////////////////////////// +template <typename T, typename A, typename B, typename C> +inline typename impl::make_composite<construct_3<T>, A, B, C>::type +construct_(A const& a, B const& b, C const& c) +{ + typedef impl::make_composite<construct_3<T>, A, B, C> make_composite_t; + typedef typename make_composite_t::type type_t; + typedef typename make_composite_t::composite_type composite_type_t; + + return type_t(composite_type_t(construct_3<T>(), + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c) + )); +} + +#if PHOENIX_CONSTRUCT_LIMIT > 3 +////////////////////////////////// +template < + typename T, typename A, typename B, typename C, typename D +> +inline typename impl::make_composite<construct_4<T>, A, B, C, D>::type +construct_( + A const& a, B const& b, C const& c, D const& d) +{ + typedef + impl::make_composite<construct_4<T>, A, B, C, D> + make_composite_t; + typedef typename make_composite_t::type type_t; + typedef typename make_composite_t::composite_type composite_type_t; + + return type_t(composite_type_t(construct_4<T>(), + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c), + as_actor<D>::convert(d) + )); +} + +////////////////////////////////// +template < + typename T, typename A, typename B, typename C, typename D, typename E +> +inline typename impl::make_composite<construct_5<T>, A, B, C, D, E>::type +construct_( + A const& a, B const& b, C const& c, D const& d, E const& e) +{ + typedef + impl::make_composite<construct_5<T>, A, B, C, D, E> + make_composite_t; + typedef typename make_composite_t::type type_t; + typedef typename make_composite_t::composite_type composite_type_t; + + return type_t(composite_type_t(construct_5<T>(), + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c), + as_actor<D>::convert(d), + as_actor<E>::convert(e) + )); +} + +////////////////////////////////// +template < + typename T, typename A, typename B, typename C, typename D, typename E, + typename F +> +inline typename impl::make_composite<construct_6<T>, A, B, C, D, E, F>::type +construct_( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f) +{ + typedef + impl::make_composite<construct_6<T>, A, B, C, D, E, F> + make_composite_t; + typedef typename make_composite_t::type type_t; + typedef typename make_composite_t::composite_type composite_type_t; + + return type_t(composite_type_t(construct_6<T>(), + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c), + as_actor<D>::convert(d), + as_actor<E>::convert(e), + as_actor<F>::convert(f) + )); +} + +#if PHOENIX_CONSTRUCT_LIMIT > 6 +////////////////////////////////// +template < + typename T, typename A, typename B, typename C, typename D, typename E, + typename F, typename G +> +inline typename impl::make_composite<construct_7<T>, A, B, C, D, E, F, G>::type +construct_( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g) +{ + typedef + impl::make_composite<construct_7<T>, A, B, C, D, E, F, G> + make_composite_t; + typedef typename make_composite_t::type type_t; + typedef typename make_composite_t::composite_type composite_type_t; + + return type_t(composite_type_t(construct_7<T>(), + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c), + as_actor<D>::convert(d), + as_actor<E>::convert(e), + as_actor<F>::convert(f), + as_actor<G>::convert(g) + )); +} + +////////////////////////////////// +template < + typename T, typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H +> +inline typename impl::make_composite<construct_8<T>, A, B, C, D, E, F, G, H>::type +construct_( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h) +{ + typedef + impl::make_composite<construct_8<T>, A, B, C, D, E, F, G, H> + make_composite_t; + typedef typename make_composite_t::type type_t; + typedef typename make_composite_t::composite_type composite_type_t; + + return type_t(composite_type_t(construct_8<T>(), + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c), + as_actor<D>::convert(d), + as_actor<E>::convert(e), + as_actor<F>::convert(f), + as_actor<G>::convert(g), + as_actor<H>::convert(h) + )); +} + +////////////////////////////////// +template < + typename T, typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I +> +inline typename impl::make_composite<construct_9<T>, A, B, C, D, E, F, G, H, I>::type +construct_( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i) +{ + typedef + impl::make_composite<construct_9<T>, A, B, C, D, E, F, G, H, I> + make_composite_t; + typedef typename make_composite_t::type type_t; + typedef typename make_composite_t::composite_type composite_type_t; + + return type_t(composite_type_t(construct_9<T>(), + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c), + as_actor<D>::convert(d), + as_actor<E>::convert(e), + as_actor<F>::convert(f), + as_actor<G>::convert(g), + as_actor<H>::convert(h), + as_actor<I>::convert(i) + )); +} + +#if PHOENIX_CONSTRUCT_LIMIT > 9 +////////////////////////////////// +template < + typename T, typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J +> +inline typename impl::make_composite< + construct_10<T>, A, B, C, D, E, F, G, H, I, J>::type +construct_( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j) +{ + typedef + impl::make_composite< + construct_10<T>, A, B, C, D, E, F, G, H, I, J + > + make_composite_t; + typedef typename make_composite_t::type type_t; + typedef typename make_composite_t::composite_type composite_type_t; + + return type_t(composite_type_t(construct_10<T>(), + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c), + as_actor<D>::convert(d), + as_actor<E>::convert(e), + as_actor<F>::convert(f), + as_actor<G>::convert(g), + as_actor<H>::convert(h), + as_actor<I>::convert(i), + as_actor<J>::convert(j) + )); +} + +////////////////////////////////// +template < + typename T, typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, typename K +> +inline typename impl::make_composite< + construct_11<T>, A, B, C, D, E, F, G, H, I, J, K>::type +construct_( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k) +{ + typedef + impl::make_composite< + construct_11<T>, A, B, C, D, E, F, G, H, I, J, K + > + make_composite_t; + typedef typename make_composite_t::type type_t; + typedef typename make_composite_t::composite_type composite_type_t; + + return type_t(composite_type_t(construct_11<T>(), + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c), + as_actor<D>::convert(d), + as_actor<E>::convert(e), + as_actor<F>::convert(f), + as_actor<G>::convert(g), + as_actor<H>::convert(h), + as_actor<I>::convert(i), + as_actor<J>::convert(j), + as_actor<K>::convert(k) + )); +} + +////////////////////////////////// +template < + typename T, typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, typename K, + typename L +> +inline typename impl::make_composite< + construct_12<T>, A, B, C, D, E, F, G, H, I, J, K, L>::type +construct_( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k, L const& l) +{ + typedef + impl::make_composite< + construct_12<T>, A, B, C, D, E, F, G, H, I, J, K, L + > + make_composite_t; + typedef typename make_composite_t::type type_t; + typedef typename make_composite_t::composite_type composite_type_t; + + return type_t(composite_type_t(construct_12<T>(), + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c), + as_actor<D>::convert(d), + as_actor<E>::convert(e), + as_actor<F>::convert(f), + as_actor<G>::convert(g), + as_actor<H>::convert(h), + as_actor<I>::convert(i), + as_actor<J>::convert(j), + as_actor<K>::convert(k), + as_actor<L>::convert(l) + )); +} + +#if PHOENIX_CONSTRUCT_LIMIT > 12 +////////////////////////////////// +template < + typename T, typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, typename K, + typename L, typename M +> +inline typename impl::make_composite< + construct_13<T>, A, B, C, D, E, F, G, H, I, J, K, L, M>::type +construct_( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k, L const& l, M const& m) +{ + typedef + impl::make_composite< + construct_13<T>, A, B, C, D, E, F, G, H, I, J, K, L, M + > + make_composite_t; + typedef typename make_composite_t::type type_t; + typedef typename make_composite_t::composite_type composite_type_t; + + return type_t(composite_type_t(construct_13<T>(), + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c), + as_actor<D>::convert(d), + as_actor<E>::convert(e), + as_actor<F>::convert(f), + as_actor<G>::convert(g), + as_actor<H>::convert(h), + as_actor<I>::convert(i), + as_actor<J>::convert(j), + as_actor<K>::convert(k), + as_actor<L>::convert(l), + as_actor<M>::convert(m) + )); +} + +////////////////////////////////// +template < + typename T, typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, typename K, + typename L, typename M, typename N +> +inline typename impl::make_composite< + construct_14<T>, A, B, C, D, E, F, G, H, I, J, K, L, M>::type +construct_( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k, L const& l, M const& m, N const& n) +{ + typedef + impl::make_composite< + construct_14<T>, A, B, C, D, E, F, G, H, I, J, K, L, M, N + > + make_composite_t; + typedef typename make_composite_t::type type_t; + typedef typename make_composite_t::composite_type composite_type_t; + + return type_t(composite_type_t(construct_14<T>(), + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c), + as_actor<D>::convert(d), + as_actor<E>::convert(e), + as_actor<F>::convert(f), + as_actor<G>::convert(g), + as_actor<H>::convert(h), + as_actor<I>::convert(i), + as_actor<J>::convert(j), + as_actor<K>::convert(k), + as_actor<L>::convert(l), + as_actor<M>::convert(m), + as_actor<N>::convert(n) + )); +} + +////////////////////////////////// +template < + typename T, typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, typename K, + typename L, typename M, typename N, typename O +> +inline typename impl::make_composite< + construct_15<T>, A, B, C, D, E, F, G, H, I, J, K, L, M, O>::type +construct_( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k, L const& l, M const& m, N const& n, O const& o) +{ + typedef + impl::make_composite< + construct_15<T>, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O + > + make_composite_t; + typedef typename make_composite_t::type type_t; + typedef typename make_composite_t::composite_type composite_type_t; + + return type_t(composite_type_t(construct_15<T>(), + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c), + as_actor<D>::convert(d), + as_actor<E>::convert(e), + as_actor<F>::convert(f), + as_actor<G>::convert(g), + as_actor<H>::convert(h), + as_actor<I>::convert(i), + as_actor<J>::convert(j), + as_actor<K>::convert(k), + as_actor<L>::convert(l), + as_actor<M>::convert(m), + as_actor<N>::convert(n), + as_actor<O>::convert(o) + )); +} + +#endif +#endif +#endif +#endif + +/////////////////////////////////////////////////////////////////////////////// +} // namespace phoenix + +#endif // PHOENIX_CASTS_HPP diff --git a/boost/spirit/home/classic/phoenix/closures.hpp b/boost/spirit/home/classic/phoenix/closures.hpp new file mode 100644 index 0000000000..6493e387a3 --- /dev/null +++ b/boost/spirit/home/classic/phoenix/closures.hpp @@ -0,0 +1,446 @@ +/*============================================================================= + Phoenix V1.2.1 + Copyright (c) 2001-2002 Joel de Guzman + MT code Copyright (c) 2002-2003 Martin Wille + + 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 CLASSIC_PHOENIX_CLOSURES_HPP +#define CLASSIC_PHOENIX_CLOSURES_HPP + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/spirit/home/classic/phoenix/actor.hpp> +#include <boost/assert.hpp> + +#ifdef PHOENIX_THREADSAFE +#include <boost/thread/tss.hpp> +#include <boost/thread/once.hpp> +#endif + +/////////////////////////////////////////////////////////////////////////////// +namespace phoenix { + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(push) +#pragma warning(disable:4512) //assignment operator could not be generated +#endif + +/////////////////////////////////////////////////////////////////////////////// +// +// Adaptable closures +// +// The framework will not be complete without some form of closures +// support. Closures encapsulate a stack frame where local +// variables are created upon entering a function and destructed +// upon exiting. Closures provide an environment for local +// variables to reside. Closures can hold heterogeneous types. +// +// Phoenix closures are true hardware stack based closures. At the +// very least, closures enable true reentrancy in lambda functions. +// A closure provides access to a function stack frame where local +// variables reside. Modeled after Pascal nested stack frames, +// closures can be nested just like nested functions where code in +// inner closures may access local variables from in-scope outer +// closures (accessing inner scopes from outer scopes is an error +// and will cause a run-time assertion failure). +// +// There are three (3) interacting classes: +// +// 1) closure: +// +// At the point of declaration, a closure does not yet create a +// stack frame nor instantiate any variables. A closure declaration +// declares the types and names[note] of the local variables. The +// closure class is meant to be subclassed. It is the +// responsibility of a closure subclass to supply the names for +// each of the local variable in the closure. Example: +// +// struct my_closure : closure<int, string, double> { +// +// member1 num; // names the 1st (int) local variable +// member2 message; // names the 2nd (string) local variable +// member3 real; // names the 3rd (double) local variable +// }; +// +// my_closure clos; +// +// Now that we have a closure 'clos', its local variables can be +// accessed lazily using the dot notation. Each qualified local +// variable can be used just like any primitive actor (see +// primitives.hpp). Examples: +// +// clos.num = 30 +// clos.message = arg1 +// clos.real = clos.num * 1e6 +// +// The examples above are lazily evaluated. As usual, these +// expressions return composite actors that will be evaluated +// through a second function call invocation (see operators.hpp). +// Each of the members (clos.xxx) is an actor. As such, applying +// the operator() will reveal its identity: +// +// clos.num() // will return the current value of clos.num +// +// *** [note] Acknowledgement: Juan Carlos Arevalo-Baeza (JCAB) +// introduced and initilally implemented the closure member names +// that uses the dot notation. +// +// 2) closure_member +// +// The named local variables of closure 'clos' above are actually +// closure members. The closure_member class is an actor and +// conforms to its conceptual interface. member1..memberN are +// predefined typedefs that correspond to each of the listed types +// in the closure template parameters. +// +// 3) closure_frame +// +// When a closure member is finally evaluated, it should refer to +// an actual instance of the variable in the hardware stack. +// Without doing so, the process is not complete and the evaluated +// member will result to an assertion failure. Remember that the +// closure is just a declaration. The local variables that a +// closure refers to must still be instantiated. +// +// The closure_frame class does the actual instantiation of the +// local variables and links these variables with the closure and +// all its members. There can be multiple instances of +// closure_frames typically situated in the stack inside a +// function. Each closure_frame instance initiates a stack frame +// with a new set of closure local variables. Example: +// +// void foo() +// { +// closure_frame<my_closure> frame(clos); +// /* do something */ +// } +// +// where 'clos' is an instance of our closure 'my_closure' above. +// Take note that the usage above precludes locally declared +// classes. If my_closure is a locally declared type, we can still +// use its self_type as a paramater to closure_frame: +// +// closure_frame<my_closure::self_type> frame(clos); +// +// Upon instantiation, the closure_frame links the local variables +// to the closure. The previous link to another closure_frame +// instance created before is saved. Upon destruction, the +// closure_frame unlinks itself from the closure and relinks the +// preceding closure_frame prior to this instance. +// +// The local variables in the closure 'clos' above is default +// constructed in the stack inside function 'foo'. Once 'foo' is +// exited, all of these local variables are destructed. In some +// cases, default construction is not desirable and we need to +// initialize the local closure variables with some values. This +// can be done by passing in the initializers in a compatible +// tuple. A compatible tuple is one with the same number of +// elements as the destination and where each element from the +// destination can be constructed from each corresponding element +// in the source. Example: +// +// tuple<int, char const*, int> init(123, "Hello", 1000); +// closure_frame<my_closure> frame(clos, init); +// +// Here now, our closure_frame's variables are initialized with +// int: 123, char const*: "Hello" and int: 1000. +// +/////////////////////////////////////////////////////////////////////////////// + +namespace impl +{ + /////////////////////////////////////////////////////////////////////// + // closure_frame_holder is a simple class that encapsulates the + // storage for a frame pointer. It uses thread specific data in + // case when multithreading is enabled, an ordinary pointer otherwise + // + // it has get() and set() member functions. set() has to be used + // _after_ get(). get() contains intialisation code in the multi + // threading case + // + // closure_frame_holder is used by the closure<> class to store + // the pointer to the current frame. + // +#ifndef PHOENIX_THREADSAFE + template <typename FrameT> + struct closure_frame_holder + { + typedef FrameT frame_t; + typedef frame_t *frame_ptr; + + closure_frame_holder() : frame(0) {} + + frame_ptr &get() { return frame; } + void set(frame_t *f) { frame = f; } + + private: + frame_ptr frame; + + // no copies, no assignments + closure_frame_holder(closure_frame_holder const &); + closure_frame_holder &operator=(closure_frame_holder const &); + }; +#else + template <typename FrameT> + struct closure_frame_holder + { + typedef FrameT frame_t; + typedef frame_t *frame_ptr; + + closure_frame_holder() : tsp_frame() {} + + frame_ptr &get() + { + if (!tsp_frame.get()) + tsp_frame.reset(new frame_ptr(0)); + return *tsp_frame; + } + void set(frame_ptr f) + { + *tsp_frame = f; + } + + private: + boost::thread_specific_ptr<frame_ptr> tsp_frame; + + // no copies, no assignments + closure_frame_holder(closure_frame_holder const &); + closure_frame_holder &operator=(closure_frame_holder const &); + }; +#endif +} // namespace phoenix::impl + +/////////////////////////////////////////////////////////////////////////////// +// +// closure_frame class +// +/////////////////////////////////////////////////////////////////////////////// +template <typename ClosureT> +class closure_frame : public ClosureT::tuple_t { + +public: + + closure_frame(ClosureT const& clos) + : ClosureT::tuple_t(), save(clos.frame.get()), frame(clos.frame) + { clos.frame.set(this); } + + template <typename TupleT> + closure_frame(ClosureT const& clos, TupleT const& init) + : ClosureT::tuple_t(init), save(clos.frame.get()), frame(clos.frame) + { clos.frame.set(this); } + + ~closure_frame() + { frame.set(save); } + +private: + + closure_frame(closure_frame const&); // no copy + closure_frame& operator=(closure_frame const&); // no assign + + closure_frame* save; + impl::closure_frame_holder<closure_frame>& frame; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// closure_member class +// +/////////////////////////////////////////////////////////////////////////////// +template <int N, typename ClosureT> +class closure_member { + +public: + + typedef typename ClosureT::tuple_t tuple_t; + + closure_member() + : frame(ClosureT::closure_frame_holder_ref()) {} + + template <typename TupleT> + struct result { + + typedef typename tuple_element< + N, typename ClosureT::tuple_t + >::rtype type; + }; + + template <typename TupleT> + typename tuple_element<N, typename ClosureT::tuple_t>::rtype + eval(TupleT const& /*args*/) const + { + using namespace std; + BOOST_ASSERT(frame.get() != 0); + return (*frame.get())[tuple_index<N>()]; + } + +private: + impl::closure_frame_holder<typename ClosureT::closure_frame_t> &frame; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// closure class +// +/////////////////////////////////////////////////////////////////////////////// +template < + typename T0 = nil_t + , typename T1 = nil_t + , typename T2 = nil_t + +#if PHOENIX_LIMIT > 3 + , typename T3 = nil_t + , typename T4 = nil_t + , typename T5 = nil_t + +#if PHOENIX_LIMIT > 6 + , typename T6 = nil_t + , typename T7 = nil_t + , typename T8 = nil_t + +#if PHOENIX_LIMIT > 9 + , typename T9 = nil_t + , typename T10 = nil_t + , typename T11 = nil_t + +#if PHOENIX_LIMIT > 12 + , typename T12 = nil_t + , typename T13 = nil_t + , typename T14 = nil_t + +#endif +#endif +#endif +#endif +> +class closure { + +public: + + typedef tuple< + T0, T1, T2 +#if PHOENIX_LIMIT > 3 + , T3, T4, T5 +#if PHOENIX_LIMIT > 6 + , T6, T7, T8 +#if PHOENIX_LIMIT > 9 + , T9, T10, T11 +#if PHOENIX_LIMIT > 12 + , T12, T13, T14 +#endif +#endif +#endif +#endif + > tuple_t; + + typedef closure< + T0, T1, T2 +#if PHOENIX_LIMIT > 3 + , T3, T4, T5 +#if PHOENIX_LIMIT > 6 + , T6, T7, T8 +#if PHOENIX_LIMIT > 9 + , T9, T10, T11 +#if PHOENIX_LIMIT > 12 + , T12, T13, T14 +#endif +#endif +#endif +#endif + > self_t; + + typedef closure_frame<self_t> closure_frame_t; + + closure() + : frame() { closure_frame_holder_ref(&frame); } + + typedef actor<closure_member<0, self_t> > member1; + typedef actor<closure_member<1, self_t> > member2; + typedef actor<closure_member<2, self_t> > member3; + +#if PHOENIX_LIMIT > 3 + typedef actor<closure_member<3, self_t> > member4; + typedef actor<closure_member<4, self_t> > member5; + typedef actor<closure_member<5, self_t> > member6; + +#if PHOENIX_LIMIT > 6 + typedef actor<closure_member<6, self_t> > member7; + typedef actor<closure_member<7, self_t> > member8; + typedef actor<closure_member<8, self_t> > member9; + +#if PHOENIX_LIMIT > 9 + typedef actor<closure_member<9, self_t> > member10; + typedef actor<closure_member<10, self_t> > member11; + typedef actor<closure_member<11, self_t> > member12; + +#if PHOENIX_LIMIT > 12 + typedef actor<closure_member<12, self_t> > member13; + typedef actor<closure_member<13, self_t> > member14; + typedef actor<closure_member<14, self_t> > member15; + +#endif +#endif +#endif +#endif + +#if !defined(__MWERKS__) || (__MWERKS__ > 0x3002) +private: +#endif + + closure(closure const&); // no copy + closure& operator=(closure const&); // no assign + +#if !defined(__MWERKS__) || (__MWERKS__ > 0x3002) + template <int N, typename ClosureT> + friend class closure_member; + + template <typename ClosureT> + friend class closure_frame; +#endif + + typedef impl::closure_frame_holder<closure_frame_t> holder_t; + +#ifdef PHOENIX_THREADSAFE + static boost::thread_specific_ptr<holder_t*> & + tsp_frame_instance() + { + static boost::thread_specific_ptr<holder_t*> the_instance; + return the_instance; + } + + static void + tsp_frame_instance_init() + { + tsp_frame_instance(); + } +#endif + + static holder_t & + closure_frame_holder_ref(holder_t* holder_ = 0) + { +#ifdef PHOENIX_THREADSAFE + static boost::once_flag been_here = BOOST_ONCE_INIT; + boost::call_once(been_here, tsp_frame_instance_init); + boost::thread_specific_ptr<holder_t*> &tsp_frame = tsp_frame_instance(); + if (!tsp_frame.get()) + tsp_frame.reset(new holder_t *(0)); + holder_t *& holder = *tsp_frame; +#else + static holder_t* holder = 0; +#endif + if (holder_ != 0) + holder = holder_; + return *holder; + } + + mutable holder_t frame; +}; + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(pop) +#endif + +} + // namespace phoenix + +#endif diff --git a/boost/spirit/home/classic/phoenix/composite.hpp b/boost/spirit/home/classic/phoenix/composite.hpp new file mode 100644 index 0000000000..3fed61de30 --- /dev/null +++ b/boost/spirit/home/classic/phoenix/composite.hpp @@ -0,0 +1,1431 @@ +/*============================================================================= + Phoenix V1.2.1 + Copyright (c) 2001-2002 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) +==============================================================================*/ +#ifndef PHOENIX_COMPOSITE_HPP +#define PHOENIX_COMPOSITE_HPP + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/spirit/home/classic/phoenix/actor.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace phoenix { + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(push) +#pragma warning(disable:4512) //assignment operator could not be generated +#endif + +/////////////////////////////////////////////////////////////////////////////// +// +// composite class +// +// A composite is an actor base class composed of zero or more +// actors (see actor.hpp) and an operation. A composite is itself +// an actor superclass and conforms to its conceptual interface. +// Its eval member function un-funnels the tupled actual arguments +// from the tuple by invoking each of the actors' eval member +// function. The results of each are then passed on as arguments to +// the operation. Specializations are provided to handle different +// numbers of actors. +// +// Schematically: +// +// actor0.eval(tupled_args) --> arg0 --> | +// actor1.eval(tupled_args) --> arg1 --> | +// actor2.eval(tupled_args) --> arg3 --> | --> operation(arg0...argN) +// ... | +// actorN.eval(tupled_args) --> argN --> | +// +// The operation can be any suitable functor that can accept the +// arguments passed in by the composite. The operation is expected +// to have a member operator() that carries out the actual +// operation. There should be a one to one correspondence between +// actors of the composite and the arguments of the operation's +// member operator(). +// +// The operation is also expected to have a nested template class +// result<T0...TN>. The nested template class result should have a +// typedef 'type' that reflects the return type of its member +// operator(). This is essentially a type computer that answers the +// metaprogramming question "Given arguments of type T0...TN, what +// will be its operator()'s return type?". +// +// There is a special case for operations that accept no arguments. +// Such nullary operations are only required to define a typedef +// result_type that reflects the return type of its operator(). +// +// Here's an example of a simple operation that squares a number: +// +// struct square { +// +// template <typename ArgT> +// struct result { typedef ArgT type; }; +// +// template <typename ArgT> +// ArgT operator()(ArgT n) const { return n * n; } +// }; +// +// As can be seen, operations can be polymorphic. Its arguments and +// return type are not fixed to a particular type. The example +// above for example, can handle any ArgT type as long as it has a +// multiplication operator. +// +// Composites are not created directly. Instead, there are meta- +// programs provided that indirectly create composites. See +// operators.hpp, binders.hpp and functions.hpp for examples. +// +/////////////////////////////////////////////////////////////////////////////// +template < + typename OperationT + , typename A = nil_t + , typename B = nil_t + , typename C = nil_t + +#if PHOENIX_LIMIT > 3 + , typename D = nil_t + , typename E = nil_t + , typename F = nil_t + +#if PHOENIX_LIMIT > 6 + , typename G = nil_t + , typename H = nil_t + , typename I = nil_t + +#if PHOENIX_LIMIT > 9 + , typename J = nil_t + , typename K = nil_t + , typename L = nil_t + +#if PHOENIX_LIMIT > 12 + , typename M = nil_t + , typename N = nil_t + , typename O = nil_t + +#endif +#endif +#endif +#endif + + , typename NU = nil_t // Not used +> +struct composite; + +/////////////////////////////////////////////////////////////////////////////// +// +// composite <0 actor> class +// +/////////////////////////////////////////////////////////////////////////////// +template <typename OperationT, typename TupleT> +struct composite0_result { + + typedef typename OperationT::result_type type; +}; + +////////////////////////////////// +template <typename OperationT> +struct composite<OperationT, + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 3 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 6 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif +#endif +#endif + nil_t // Unused +> { + + typedef composite<OperationT> self_t; + + template <typename TupleT> + struct result { + + typedef typename composite0_result< + OperationT, TupleT + >::type type; + }; + + composite(OperationT const& op_) + : op(op_) {} + + template <typename TupleT> + typename OperationT::result_type + eval(TupleT const& /*args*/) const + { + return op(); + } + + mutable OperationT op; // operation +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// composite <1 actor> class +// +/////////////////////////////////////////////////////////////////////////////// +template <typename OperationT, typename TupleT, + typename A> +struct composite1_result { + + typedef typename OperationT::template result< + typename actor_result<A, TupleT>::plain_type + >::type type; +}; + +////////////////////////////////// +template <typename OperationT, + typename A> +struct composite<OperationT, + A, nil_t, nil_t, +#if PHOENIX_LIMIT > 3 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 6 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif +#endif +#endif + nil_t // Unused +> { + + typedef composite<OperationT, A> self_t; + + template <typename TupleT> + struct result { + + typedef typename composite1_result< + OperationT, TupleT, A + >::type type; + }; + + composite(OperationT const& op_, + A const& a_) + : op(op_), a(a_) {} + + template <typename TupleT> + typename actor_result<self_t, TupleT>::type + eval(TupleT const& args) const + { + typename actor_result<A, TupleT>::type ra = a.eval(args); + return op(ra); + } + + mutable OperationT op; // operation + A a; // actors +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// composite <2 actors> class +// +/////////////////////////////////////////////////////////////////////////////// +template <typename OperationT, typename TupleT, + typename A, typename B> +struct composite2_result { + + typedef typename OperationT::template result< + typename actor_result<A, TupleT>::plain_type, + typename actor_result<B, TupleT>::plain_type + >::type type; +}; + +////////////////////////////////// +template <typename OperationT, + typename A, typename B> +struct composite<OperationT, + A, B, nil_t, +#if PHOENIX_LIMIT > 3 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 6 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif +#endif +#endif + nil_t // Unused +> { + + typedef composite<OperationT, A, B> self_t; + + template <typename TupleT> + struct result { + + typedef typename composite2_result< + OperationT, TupleT, A, B + >::type type; + }; + + composite(OperationT const& op_, + A const& a_, B const& b_) + : op(op_), a(a_), b(b_) {} + + template <typename TupleT> + typename actor_result<self_t, TupleT>::type + eval(TupleT const& args) const + { + typename actor_result<A, TupleT>::type ra = a.eval(args); + typename actor_result<B, TupleT>::type rb = b.eval(args); + return op(ra, rb); + } + + mutable OperationT op; // operation + A a; B b; // actors +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// composite <3 actors> class +// +/////////////////////////////////////////////////////////////////////////////// +template <typename OperationT, typename TupleT, + typename A, typename B, typename C> +struct composite3_result { + + typedef typename OperationT::template result< + typename actor_result<A, TupleT>::plain_type, + typename actor_result<B, TupleT>::plain_type, + typename actor_result<C, TupleT>::plain_type + >::type type; +}; + +////////////////////////////////// +template <typename OperationT, + typename A, typename B, typename C> +struct composite<OperationT, + A, B, C, +#if PHOENIX_LIMIT > 3 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 6 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif +#endif +#endif + nil_t // Unused +> { + + typedef composite<OperationT, A, B, C> self_t; + + template <typename TupleT> + struct result { + + typedef typename composite3_result< + OperationT, TupleT, A, B, C + >::type type; + }; + + composite(OperationT const& op_, + A const& a_, B const& b_, C const& c_) + : op(op_), a(a_), b(b_), c(c_) {} + + template <typename TupleT> + typename actor_result<self_t, TupleT>::type + eval(TupleT const& args) const + { + typename actor_result<A, TupleT>::type ra = a.eval(args); + typename actor_result<B, TupleT>::type rb = b.eval(args); + typename actor_result<C, TupleT>::type rc = c.eval(args); + return op(ra, rb, rc); + } + + mutable OperationT op; // operation + A a; B b; C c; // actors +}; + +#if PHOENIX_LIMIT > 3 +/////////////////////////////////////////////////////////////////////////////// +// +// composite <4 actors> class +// +/////////////////////////////////////////////////////////////////////////////// +template <typename OperationT, typename TupleT, + typename A, typename B, typename C, typename D> +struct composite4_result { + + typedef typename OperationT::template result< + typename actor_result<A, TupleT>::plain_type, + typename actor_result<B, TupleT>::plain_type, + typename actor_result<C, TupleT>::plain_type, + typename actor_result<D, TupleT>::plain_type + >::type type; +}; + +////////////////////////////////// +template <typename OperationT, + typename A, typename B, typename C, typename D> +struct composite<OperationT, + A, B, C, D, nil_t, nil_t, +#if PHOENIX_LIMIT > 6 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif +#endif + nil_t // Unused +> { + + typedef composite<OperationT, A, B, C, D> self_t; + + template <typename TupleT> + struct result { + + typedef typename composite4_result< + OperationT, TupleT, A, B, C, D + >::type type; + }; + + composite(OperationT const& op_, + A const& a_, B const& b_, C const& c_, D const& d_) + : op(op_), a(a_), b(b_), c(c_), d(d_) {} + + template <typename TupleT> + typename actor_result<self_t, TupleT>::type + eval(TupleT const& args) const + { + typename actor_result<A, TupleT>::type ra = a.eval(args); + typename actor_result<B, TupleT>::type rb = b.eval(args); + typename actor_result<C, TupleT>::type rc = c.eval(args); + typename actor_result<D, TupleT>::type rd = d.eval(args); + return op(ra, rb, rc, rd); + } + + mutable OperationT op; // operation + A a; B b; C c; D d; // actors +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// composite <5 actors> class +// +/////////////////////////////////////////////////////////////////////////////// +template <typename OperationT, typename TupleT, + typename A, typename B, typename C, typename D, typename E> +struct composite5_result { + + typedef typename OperationT::template result< + typename actor_result<A, TupleT>::plain_type, + typename actor_result<B, TupleT>::plain_type, + typename actor_result<C, TupleT>::plain_type, + typename actor_result<D, TupleT>::plain_type, + typename actor_result<E, TupleT>::plain_type + >::type type; +}; + +////////////////////////////////// +template <typename OperationT, + typename A, typename B, typename C, typename D, typename E> +struct composite<OperationT, + A, B, C, D, E, nil_t, +#if PHOENIX_LIMIT > 6 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif +#endif + nil_t // Unused +> { + + typedef composite<OperationT, A, B, C, D, E> self_t; + + template <typename TupleT> + struct result { + + typedef typename composite5_result< + OperationT, TupleT, A, B, C, D, E + >::type type; + }; + + composite(OperationT const& op_, + A const& a_, B const& b_, C const& c_, D const& d_, E const& e_) + : op(op_), a(a_), b(b_), c(c_), d(d_), e(e_) {} + + template <typename TupleT> + typename actor_result<self_t, TupleT>::type + eval(TupleT const& args) const + { + typename actor_result<A, TupleT>::type ra = a.eval(args); + typename actor_result<B, TupleT>::type rb = b.eval(args); + typename actor_result<C, TupleT>::type rc = c.eval(args); + typename actor_result<D, TupleT>::type rd = d.eval(args); + typename actor_result<E, TupleT>::type re = e.eval(args); + return op(ra, rb, rc, rd, re); + } + + mutable OperationT op; // operation + A a; B b; C c; D d; E e; // actors +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// composite <6 actors> class +// +/////////////////////////////////////////////////////////////////////////////// +template <typename OperationT, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F> +struct composite6_result { + + typedef typename OperationT::template result< + typename actor_result<A, TupleT>::plain_type, + typename actor_result<B, TupleT>::plain_type, + typename actor_result<C, TupleT>::plain_type, + typename actor_result<D, TupleT>::plain_type, + typename actor_result<E, TupleT>::plain_type, + typename actor_result<F, TupleT>::plain_type + >::type type; +}; + +////////////////////////////////// +template <typename OperationT, + typename A, typename B, typename C, typename D, typename E, + typename F> +struct composite<OperationT, + A, B, C, D, E, F, +#if PHOENIX_LIMIT > 6 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif +#endif + nil_t // Unused +> { + + typedef composite<OperationT, A, B, C, D, E, F> self_t; + + template <typename TupleT> + struct result { + + typedef typename composite6_result< + OperationT, TupleT, A, B, C, D, E, F + >::type type; + }; + + composite(OperationT const& op_, + A const& a_, B const& b_, C const& c_, D const& d_, E const& e_, + F const& f_) + : op(op_), a(a_), b(b_), c(c_), d(d_), e(e_), + f(f_) {} + + template <typename TupleT> + typename actor_result<self_t, TupleT>::type + eval(TupleT const& args) const + { + typename actor_result<A, TupleT>::type ra = a.eval(args); + typename actor_result<B, TupleT>::type rb = b.eval(args); + typename actor_result<C, TupleT>::type rc = c.eval(args); + typename actor_result<D, TupleT>::type rd = d.eval(args); + typename actor_result<E, TupleT>::type re = e.eval(args); + typename actor_result<F, TupleT>::type rf = f.eval(args); + return op(ra, rb, rc, rd, re, rf); + } + + mutable OperationT op; // operation + A a; B b; C c; D d; E e; F f; // actors +}; + +#if PHOENIX_LIMIT > 6 +/////////////////////////////////////////////////////////////////////////////// +// +// composite <7 actors> class +// +/////////////////////////////////////////////////////////////////////////////// +template <typename OperationT, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G> +struct composite7_result { + + typedef typename OperationT::template result< + typename actor_result<A, TupleT>::plain_type, + typename actor_result<B, TupleT>::plain_type, + typename actor_result<C, TupleT>::plain_type, + typename actor_result<D, TupleT>::plain_type, + typename actor_result<E, TupleT>::plain_type, + typename actor_result<F, TupleT>::plain_type, + typename actor_result<G, TupleT>::plain_type + >::type type; +}; + +////////////////////////////////// +template <typename OperationT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G> +struct composite<OperationT, + A, B, C, D, E, F, G, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif + nil_t // Unused +> { + + typedef composite<OperationT, A, B, C, D, E, F, G> self_t; + + template <typename TupleT> + struct result { + + typedef typename composite7_result< + OperationT, TupleT, A, B, C, D, E, F, G + >::type type; + }; + + composite(OperationT const& op_, + A const& a_, B const& b_, C const& c_, D const& d_, E const& e_, + F const& f_, G const& g_) + : op(op_), a(a_), b(b_), c(c_), d(d_), e(e_), + f(f_), g(g_) {} + + template <typename TupleT> + typename actor_result<self_t, TupleT>::type + eval(TupleT const& args) const + { + typename actor_result<A, TupleT>::type ra = a.eval(args); + typename actor_result<B, TupleT>::type rb = b.eval(args); + typename actor_result<C, TupleT>::type rc = c.eval(args); + typename actor_result<D, TupleT>::type rd = d.eval(args); + typename actor_result<E, TupleT>::type re = e.eval(args); + typename actor_result<F, TupleT>::type rf = f.eval(args); + typename actor_result<G, TupleT>::type rg = g.eval(args); + return op(ra, rb, rc, rd, re, rf, rg); + } + + mutable OperationT op; // operation + A a; B b; C c; D d; E e; F f; G g; // actors +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// composite <8 actors> class +// +/////////////////////////////////////////////////////////////////////////////// +template <typename OperationT, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H> +struct composite8_result { + + typedef typename OperationT::template result< + typename actor_result<A, TupleT>::plain_type, + typename actor_result<B, TupleT>::plain_type, + typename actor_result<C, TupleT>::plain_type, + typename actor_result<D, TupleT>::plain_type, + typename actor_result<E, TupleT>::plain_type, + typename actor_result<F, TupleT>::plain_type, + typename actor_result<G, TupleT>::plain_type, + typename actor_result<H, TupleT>::plain_type + >::type type; +}; + +////////////////////////////////// +template <typename OperationT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H> +struct composite<OperationT, + A, B, C, D, E, F, G, H, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif + nil_t // Unused +> { + + typedef composite<OperationT, A, B, C, D, E, F, G, H> self_t; + + template <typename TupleT> + struct result { + + typedef typename composite8_result< + OperationT, TupleT, A, B, C, D, E, F, G, H + >::type type; + }; + + composite(OperationT const& op_, + A const& a_, B const& b_, C const& c_, D const& d_, E const& e_, + F const& f_, G const& g_, H const& h_) + : op(op_), a(a_), b(b_), c(c_), d(d_), e(e_), + f(f_), g(g_), h(h_) {} + + template <typename TupleT> + typename actor_result<self_t, TupleT>::type + eval(TupleT const& args) const + { + typename actor_result<A, TupleT>::type ra = a.eval(args); + typename actor_result<B, TupleT>::type rb = b.eval(args); + typename actor_result<C, TupleT>::type rc = c.eval(args); + typename actor_result<D, TupleT>::type rd = d.eval(args); + typename actor_result<E, TupleT>::type re = e.eval(args); + typename actor_result<F, TupleT>::type rf = f.eval(args); + typename actor_result<G, TupleT>::type rg = g.eval(args); + typename actor_result<H, TupleT>::type rh = h.eval(args); + return op(ra, rb, rc, rd, re, rf, rg, rh); + } + + mutable OperationT op; // operation + A a; B b; C c; D d; E e; F f; G g; H h; // actors +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// composite <9 actors> class +// +/////////////////////////////////////////////////////////////////////////////// +template <typename OperationT, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I> +struct composite9_result { + + typedef typename OperationT::template result< + typename actor_result<A, TupleT>::plain_type, + typename actor_result<B, TupleT>::plain_type, + typename actor_result<C, TupleT>::plain_type, + typename actor_result<D, TupleT>::plain_type, + typename actor_result<E, TupleT>::plain_type, + typename actor_result<F, TupleT>::plain_type, + typename actor_result<G, TupleT>::plain_type, + typename actor_result<H, TupleT>::plain_type, + typename actor_result<I, TupleT>::plain_type + >::type type; +}; + +////////////////////////////////// +template <typename OperationT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I> +struct composite<OperationT, + A, B, C, D, E, F, G, H, I, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif + nil_t // Unused +> { + + typedef composite<OperationT, A, B, C, D, E, F, G, H, I> self_t; + + template <typename TupleT> + struct result { + + typedef typename composite9_result< + OperationT, TupleT, A, B, C, D, E, F, G, H, I + >::type type; + }; + + composite(OperationT const& op_, + A const& a_, B const& b_, C const& c_, D const& d_, E const& e_, + F const& f_, G const& g_, H const& h_, I const& i_) + : op(op_), a(a_), b(b_), c(c_), d(d_), e(e_), + f(f_), g(g_), h(h_), i(i_) {} + + template <typename TupleT> + typename actor_result<self_t, TupleT>::type + eval(TupleT const& args) const + { + typename actor_result<A, TupleT>::type ra = a.eval(args); + typename actor_result<B, TupleT>::type rb = b.eval(args); + typename actor_result<C, TupleT>::type rc = c.eval(args); + typename actor_result<D, TupleT>::type rd = d.eval(args); + typename actor_result<E, TupleT>::type re = e.eval(args); + typename actor_result<F, TupleT>::type rf = f.eval(args); + typename actor_result<G, TupleT>::type rg = g.eval(args); + typename actor_result<H, TupleT>::type rh = h.eval(args); + typename actor_result<I, TupleT>::type ri = i.eval(args); + return op(ra, rb, rc, rd, re, rf, rg, rh, ri); + } + + mutable OperationT op; // operation + A a; B b; C c; D d; E e; F f; G g; H h; I i; // actors +}; + +#if PHOENIX_LIMIT > 9 +/////////////////////////////////////////////////////////////////////////////// +// +// composite <10 actors> class +// +/////////////////////////////////////////////////////////////////////////////// +template <typename OperationT, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J> +struct composite10_result { + + typedef typename OperationT::template result< + typename actor_result<A, TupleT>::plain_type, + typename actor_result<B, TupleT>::plain_type, + typename actor_result<C, TupleT>::plain_type, + typename actor_result<D, TupleT>::plain_type, + typename actor_result<E, TupleT>::plain_type, + typename actor_result<F, TupleT>::plain_type, + typename actor_result<G, TupleT>::plain_type, + typename actor_result<H, TupleT>::plain_type, + typename actor_result<I, TupleT>::plain_type, + typename actor_result<J, TupleT>::plain_type + >::type type; +}; + +////////////////////////////////// +template <typename OperationT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J> +struct composite<OperationT, + A, B, C, D, E, F, G, H, I, J, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif + nil_t // Unused +> { + + typedef composite<OperationT, A, B, C, D, E, F, G, H, I, J> self_t; + + template <typename TupleT> + struct result { + + typedef typename composite10_result< + OperationT, TupleT, A, B, C, D, E, F, G, H, I, J + >::type type; + }; + + composite(OperationT const& op_, + A const& a_, B const& b_, C const& c_, D const& d_, E const& e_, + F const& f_, G const& g_, H const& h_, I const& i_, J const& j_) + : op(op_), a(a_), b(b_), c(c_), d(d_), e(e_), + f(f_), g(g_), h(h_), i(i_), j(j_) {} + + template <typename TupleT> + typename actor_result<self_t, TupleT>::type + eval(TupleT const& args) const + { + typename actor_result<A, TupleT>::type ra = a.eval(args); + typename actor_result<B, TupleT>::type rb = b.eval(args); + typename actor_result<C, TupleT>::type rc = c.eval(args); + typename actor_result<D, TupleT>::type rd = d.eval(args); + typename actor_result<E, TupleT>::type re = e.eval(args); + typename actor_result<F, TupleT>::type rf = f.eval(args); + typename actor_result<G, TupleT>::type rg = g.eval(args); + typename actor_result<H, TupleT>::type rh = h.eval(args); + typename actor_result<I, TupleT>::type ri = i.eval(args); + typename actor_result<J, TupleT>::type rj = j.eval(args); + return op(ra, rb, rc, rd, re, rf, rg, rh, ri, rj); + } + + mutable OperationT op; // operation + A a; B b; C c; D d; E e; F f; G g; H h; I i; J j; // actors +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// composite <11 actors> class +// +/////////////////////////////////////////////////////////////////////////////// +template <typename OperationT, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K> +struct composite11_result { + + typedef typename OperationT::template result< + typename actor_result<A, TupleT>::plain_type, + typename actor_result<B, TupleT>::plain_type, + typename actor_result<C, TupleT>::plain_type, + typename actor_result<D, TupleT>::plain_type, + typename actor_result<E, TupleT>::plain_type, + typename actor_result<F, TupleT>::plain_type, + typename actor_result<G, TupleT>::plain_type, + typename actor_result<H, TupleT>::plain_type, + typename actor_result<I, TupleT>::plain_type, + typename actor_result<J, TupleT>::plain_type, + typename actor_result<K, TupleT>::plain_type + >::type type; +}; + +////////////////////////////////// +template <typename OperationT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K> +struct composite<OperationT, + A, B, C, D, E, F, G, H, I, J, K, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif + nil_t // Unused +> { + + typedef composite<OperationT, + A, B, C, D, E, F, G, H, I, J, K> self_t; + + template <typename TupleT> + struct result { + + typedef typename composite11_result< + OperationT, TupleT, A, B, C, D, E, F, G, H, I, J, K + >::type type; + }; + + composite(OperationT const& op_, + A const& a_, B const& b_, C const& c_, D const& d_, E const& e_, + F const& f_, G const& g_, H const& h_, I const& i_, J const& j_, + K const& k_) + : op(op_), a(a_), b(b_), c(c_), d(d_), e(e_), + f(f_), g(g_), h(h_), i(i_), j(j_), + k(k_) {} + + template <typename TupleT> + typename actor_result<self_t, TupleT>::type + eval(TupleT const& args) const + { + typename actor_result<A, TupleT>::type ra = a.eval(args); + typename actor_result<B, TupleT>::type rb = b.eval(args); + typename actor_result<C, TupleT>::type rc = c.eval(args); + typename actor_result<D, TupleT>::type rd = d.eval(args); + typename actor_result<E, TupleT>::type re = e.eval(args); + typename actor_result<F, TupleT>::type rf = f.eval(args); + typename actor_result<G, TupleT>::type rg = g.eval(args); + typename actor_result<H, TupleT>::type rh = h.eval(args); + typename actor_result<I, TupleT>::type ri = i.eval(args); + typename actor_result<J, TupleT>::type rj = j.eval(args); + typename actor_result<K, TupleT>::type rk = k.eval(args); + return op(ra, rb, rc, rd, re, rf, rg, rh, ri, rj, rk); + } + + mutable OperationT op; // operation + A a; B b; C c; D d; E e; F f; G g; H h; I i; J j; + K k;// actors +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// composite <12 actors> class +// +/////////////////////////////////////////////////////////////////////////////// +template <typename OperationT, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L> +struct composite12_result { + + typedef typename OperationT::template result< + typename actor_result<A, TupleT>::plain_type, + typename actor_result<B, TupleT>::plain_type, + typename actor_result<C, TupleT>::plain_type, + typename actor_result<D, TupleT>::plain_type, + typename actor_result<E, TupleT>::plain_type, + typename actor_result<F, TupleT>::plain_type, + typename actor_result<G, TupleT>::plain_type, + typename actor_result<H, TupleT>::plain_type, + typename actor_result<I, TupleT>::plain_type, + typename actor_result<J, TupleT>::plain_type, + typename actor_result<K, TupleT>::plain_type, + typename actor_result<L, TupleT>::plain_type + >::type type; +}; + +////////////////////////////////// +template <typename OperationT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L> +struct composite<OperationT, + A, B, C, D, E, F, G, H, I, J, K, L, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif + nil_t // Unused +> { + + typedef composite<OperationT, + A, B, C, D, E, F, G, H, I, J, K, L> self_t; + + template <typename TupleT> + struct result { + + typedef typename composite12_result< + OperationT, TupleT, A, B, C, D, E, F, G, H, I, J, K, L + >::type type; + }; + + composite(OperationT const& op_, + A const& a_, B const& b_, C const& c_, D const& d_, E const& e_, + F const& f_, G const& g_, H const& h_, I const& i_, J const& j_, + K const& k_, L const& l_) + : op(op_), a(a_), b(b_), c(c_), d(d_), e(e_), + f(f_), g(g_), h(h_), i(i_), j(j_), + k(k_), l(l_) {} + + template <typename TupleT> + typename actor_result<self_t, TupleT>::type + eval(TupleT const& args) const + { + typename actor_result<A, TupleT>::type ra = a.eval(args); + typename actor_result<B, TupleT>::type rb = b.eval(args); + typename actor_result<C, TupleT>::type rc = c.eval(args); + typename actor_result<D, TupleT>::type rd = d.eval(args); + typename actor_result<E, TupleT>::type re = e.eval(args); + typename actor_result<F, TupleT>::type rf = f.eval(args); + typename actor_result<G, TupleT>::type rg = g.eval(args); + typename actor_result<H, TupleT>::type rh = h.eval(args); + typename actor_result<I, TupleT>::type ri = i.eval(args); + typename actor_result<J, TupleT>::type rj = j.eval(args); + typename actor_result<K, TupleT>::type rk = k.eval(args); + typename actor_result<L, TupleT>::type rl = l.eval(args); + return op(ra, rb, rc, rd, re, rf, rg, rh, ri, rj, rk, rl); + } + + mutable OperationT op; // operation + A a; B b; C c; D d; E e; F f; G g; H h; I i; J j; + K k; L l;// actors +}; + +#if PHOENIX_LIMIT > 12 +/////////////////////////////////////////////////////////////////////////////// +// +// composite <13 actors> class +// +/////////////////////////////////////////////////////////////////////////////// +template <typename OperationT, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M> +struct composite13_result { + + typedef typename OperationT::template result< + typename actor_result<A, TupleT>::plain_type, + typename actor_result<B, TupleT>::plain_type, + typename actor_result<C, TupleT>::plain_type, + typename actor_result<D, TupleT>::plain_type, + typename actor_result<E, TupleT>::plain_type, + typename actor_result<F, TupleT>::plain_type, + typename actor_result<G, TupleT>::plain_type, + typename actor_result<H, TupleT>::plain_type, + typename actor_result<I, TupleT>::plain_type, + typename actor_result<J, TupleT>::plain_type, + typename actor_result<K, TupleT>::plain_type, + typename actor_result<L, TupleT>::plain_type, + typename actor_result<M, TupleT>::plain_type + >::type type; +}; + +////////////////////////////////// +template <typename OperationT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M> +struct composite<OperationT, + A, B, C, D, E, F, G, H, I, J, K, L, M, nil_t, nil_t, nil_t +> { + + typedef composite<OperationT, + A, B, C, D, E, F, G, H, I, J, K, L, M> self_t; + + template <typename TupleT> + struct result { + + typedef typename composite13_result< + OperationT, TupleT, A, B, C, D, E, F, G, H, I, J, K, L, M + >::type type; + }; + + composite(OperationT const& op_, + A const& a_, B const& b_, C const& c_, D const& d_, E const& e_, + F const& f_, G const& g_, H const& h_, I const& i_, J const& j_, + K const& k_, L const& l_, M const& m_) + : op(op_), a(a_), b(b_), c(c_), d(d_), e(e_), + f(f_), g(g_), h(h_), i(i_), j(j_), + k(k_), l(l_), m(m_) {} + + template <typename TupleT> + typename actor_result<self_t, TupleT>::type + eval(TupleT const& args) const + { + typename actor_result<A, TupleT>::type ra = a.eval(args); + typename actor_result<B, TupleT>::type rb = b.eval(args); + typename actor_result<C, TupleT>::type rc = c.eval(args); + typename actor_result<D, TupleT>::type rd = d.eval(args); + typename actor_result<E, TupleT>::type re = e.eval(args); + typename actor_result<F, TupleT>::type rf = f.eval(args); + typename actor_result<G, TupleT>::type rg = g.eval(args); + typename actor_result<H, TupleT>::type rh = h.eval(args); + typename actor_result<I, TupleT>::type ri = i.eval(args); + typename actor_result<J, TupleT>::type rj = j.eval(args); + typename actor_result<K, TupleT>::type rk = k.eval(args); + typename actor_result<L, TupleT>::type rl = l.eval(args); + typename actor_result<M, TupleT>::type rm = m.eval(args); + return op(ra, rb, rc, rd, re, rf, rg, rh, ri, rj, rk, rl, rm); + } + + mutable OperationT op; // operation + A a; B b; C c; D d; E e; F f; G g; H h; I i; J j; + K k; L l; M m; // actors +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// composite <14 actors> class +// +/////////////////////////////////////////////////////////////////////////////// +template <typename OperationT, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M, typename N> +struct composite14_result { + + typedef typename OperationT::template result< + typename actor_result<A, TupleT>::plain_type, + typename actor_result<B, TupleT>::plain_type, + typename actor_result<C, TupleT>::plain_type, + typename actor_result<D, TupleT>::plain_type, + typename actor_result<E, TupleT>::plain_type, + typename actor_result<F, TupleT>::plain_type, + typename actor_result<G, TupleT>::plain_type, + typename actor_result<H, TupleT>::plain_type, + typename actor_result<I, TupleT>::plain_type, + typename actor_result<J, TupleT>::plain_type, + typename actor_result<K, TupleT>::plain_type, + typename actor_result<L, TupleT>::plain_type, + typename actor_result<M, TupleT>::plain_type, + typename actor_result<N, TupleT>::plain_type + >::type type; +}; + +////////////////////////////////// +template <typename OperationT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M, typename N> +struct composite<OperationT, + A, B, C, D, E, F, G, H, I, J, K, L, M, N, nil_t, nil_t +> { + + typedef composite<OperationT, + A, B, C, D, E, F, G, H, I, J, K, L, M, N> self_t; + + template <typename TupleT> + struct result { + + typedef typename composite14_result< + OperationT, TupleT, A, B, C, D, E, F, G, H, I, J, K, L, M, N + >::type type; + }; + + composite(OperationT const& op_, + A const& a_, B const& b_, C const& c_, D const& d_, E const& e_, + F const& f_, G const& g_, H const& h_, I const& i_, J const& j_, + K const& k_, L const& l_, M const& m_, N const& n_) + : op(op_), a(a_), b(b_), c(c_), d(d_), e(e_), + f(f_), g(g_), h(h_), i(i_), j(j_), + k(k_), l(l_), m(m_), n(n_) {} + + template <typename TupleT> + typename actor_result<self_t, TupleT>::type + eval(TupleT const& args) const + { + typename actor_result<A, TupleT>::type ra = a.eval(args); + typename actor_result<B, TupleT>::type rb = b.eval(args); + typename actor_result<C, TupleT>::type rc = c.eval(args); + typename actor_result<D, TupleT>::type rd = d.eval(args); + typename actor_result<E, TupleT>::type re = e.eval(args); + typename actor_result<F, TupleT>::type rf = f.eval(args); + typename actor_result<G, TupleT>::type rg = g.eval(args); + typename actor_result<H, TupleT>::type rh = h.eval(args); + typename actor_result<I, TupleT>::type ri = i.eval(args); + typename actor_result<J, TupleT>::type rj = j.eval(args); + typename actor_result<K, TupleT>::type rk = k.eval(args); + typename actor_result<L, TupleT>::type rl = l.eval(args); + typename actor_result<M, TupleT>::type rm = m.eval(args); + typename actor_result<N, TupleT>::type rn = n.eval(args); + return op(ra, rb, rc, rd, re, rf, rg, rh, ri, rj, rk, rl, rm, rn); + } + + mutable OperationT op; // operation + A a; B b; C c; D d; E e; F f; G g; H h; I i; J j; + K k; L l; M m; N n; // actors +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// composite <15 actors> class +// +/////////////////////////////////////////////////////////////////////////////// +template <typename OperationT, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M, typename N, typename O> +struct composite15_result { + + typedef typename OperationT::template result< + typename actor_result<A, TupleT>::plain_type, + typename actor_result<B, TupleT>::plain_type, + typename actor_result<C, TupleT>::plain_type, + typename actor_result<D, TupleT>::plain_type, + typename actor_result<E, TupleT>::plain_type, + typename actor_result<F, TupleT>::plain_type, + typename actor_result<G, TupleT>::plain_type, + typename actor_result<H, TupleT>::plain_type, + typename actor_result<I, TupleT>::plain_type, + typename actor_result<J, TupleT>::plain_type, + typename actor_result<K, TupleT>::plain_type, + typename actor_result<L, TupleT>::plain_type, + typename actor_result<M, TupleT>::plain_type, + typename actor_result<N, TupleT>::plain_type, + typename actor_result<O, TupleT>::plain_type + >::type type; +}; + +////////////////////////////////// +template <typename OperationT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M, typename N, typename O> +struct composite<OperationT, + A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, nil_t +> { + + typedef composite<OperationT, + A, B, C, D, E, F, G, H, I, J, K, L, M, N, O> self_t; + + template <typename TupleT> + struct result { + + typedef typename composite15_result< + OperationT, TupleT, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O + >::type type; + }; + + composite(OperationT const& op_, + A const& a_, B const& b_, C const& c_, D const& d_, E const& e_, + F const& f_, G const& g_, H const& h_, I const& i_, J const& j_, + K const& k_, L const& l_, M const& m_, N const& n_, O const& o_) + : op(op_), a(a_), b(b_), c(c_), d(d_), e(e_), + f(f_), g(g_), h(h_), i(i_), j(j_), + k(k_), l(l_), m(m_), n(n_), o(o_) {} + + template <typename TupleT> + typename actor_result<self_t, TupleT>::type + eval(TupleT const& args) const + { + typename actor_result<A, TupleT>::type ra = a.eval(args); + typename actor_result<B, TupleT>::type rb = b.eval(args); + typename actor_result<C, TupleT>::type rc = c.eval(args); + typename actor_result<D, TupleT>::type rd = d.eval(args); + typename actor_result<E, TupleT>::type re = e.eval(args); + typename actor_result<F, TupleT>::type rf = f.eval(args); + typename actor_result<G, TupleT>::type rg = g.eval(args); + typename actor_result<H, TupleT>::type rh = h.eval(args); + typename actor_result<I, TupleT>::type ri = i.eval(args); + typename actor_result<J, TupleT>::type rj = j.eval(args); + typename actor_result<K, TupleT>::type rk = k.eval(args); + typename actor_result<L, TupleT>::type rl = l.eval(args); + typename actor_result<M, TupleT>::type rm = m.eval(args); + typename actor_result<N, TupleT>::type rn = n.eval(args); + typename actor_result<O, TupleT>::type ro = o.eval(args); + return op(ra, rb, rc, rd, re, rf, rg, rh, ri, rj, rk, rl, rm, rn, ro); + } + + mutable OperationT op; // operation + A a; B b; C c; D d; E e; F f; G g; H h; I i; J j; + K k; L l; M m; N n; O o; // actors +}; + +#endif +#endif +#endif +#endif + +namespace impl { + + /////////////////////////////////////////////////////////////////////////// + // + // make_composite is basically a type computer that answers the + // question "Given types T0..TN, what composite type should I + // create <composite_type> and if I were to generate an actual + // composite, what type <type> should I return?" + // + /////////////////////////////////////////////////////////////////////////// + template < + typename OperationT + , typename A = nil_t + , typename B = nil_t + , typename C = nil_t + +#if PHOENIX_LIMIT > 3 + , typename D = nil_t + , typename E = nil_t + , typename F = nil_t + +#if PHOENIX_LIMIT > 6 + , typename G = nil_t + , typename H = nil_t + , typename I = nil_t + +#if PHOENIX_LIMIT > 9 + , typename J = nil_t + , typename K = nil_t + , typename L = nil_t + +#if PHOENIX_LIMIT > 12 + , typename M = nil_t + , typename N = nil_t + , typename O = nil_t + +#endif +#endif +#endif +#endif + > + struct make_composite { + + typedef composite<OperationT + , typename as_actor<A>::type + , typename as_actor<B>::type + , typename as_actor<C>::type + +#if PHOENIX_LIMIT > 3 + , typename as_actor<D>::type + , typename as_actor<E>::type + , typename as_actor<F>::type + +#if PHOENIX_LIMIT > 6 + , typename as_actor<G>::type + , typename as_actor<H>::type + , typename as_actor<I>::type + +#if PHOENIX_LIMIT > 9 + , typename as_actor<J>::type + , typename as_actor<K>::type + , typename as_actor<L>::type + +#if PHOENIX_LIMIT > 12 + , typename as_actor<M>::type + , typename as_actor<N>::type + , typename as_actor<O>::type + +#endif +#endif +#endif +#endif + > composite_type; + + typedef actor<composite_type> type; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // make_unary, make_binary, make_binary1, make_binary2 and + // make_binary3 utilities are provided here for easy creation of + // unary and binary composites. + // + /////////////////////////////////////////////////////////////////////////// + + ////////////////////////////////// input is an actor + template <typename OperationT, typename BaseT> + struct make_unary { + + typedef typename make_composite + <OperationT, actor<BaseT> >::type type; + + static type + construct(actor<BaseT> const& _0) + { + typedef typename make_composite + <OperationT, actor<BaseT> >::composite_type + ret_t; + + return ret_t(OperationT(), _0); + } + }; + + ////////////////////////////////// LHS is an actor, RHS is unknown + template <typename OperationT, typename BaseT, typename B> + struct make_binary1 { + + typedef typename make_composite + <OperationT, actor<BaseT>, B>::type type; + + static type + construct(actor<BaseT> const& _0, B const& _1) + { + typedef typename make_composite + <OperationT, actor<BaseT>, B>::composite_type + ret_t; + + return ret_t(OperationT(), _0, as_actor<B>::convert(_1)); + } + }; + + ////////////////////////////////// LHS is unknown, RHS is an actor + template <typename OperationT, typename A, typename BaseT> + struct make_binary2 { + + typedef typename make_composite + <OperationT, A, actor<BaseT> >::type type; + + static type + construct(A const& _0, actor<BaseT> const& _1) + { + typedef typename make_composite + <OperationT, A, actor<BaseT> >::composite_type + ret_t; + + return ret_t(OperationT(), as_actor<A>::convert(_0), _1); + } + }; + + ////////////////////////////////// Both LHS and RHS are actors + template <typename OperationT, typename BaseA, typename BaseB> + struct make_binary3 { + + typedef typename make_composite + <OperationT, actor<BaseA>, actor<BaseB> >::type type; + + static type + construct(actor<BaseA> const& _0, actor<BaseB> const& _1) + { + typedef typename make_composite + <OperationT, actor<BaseA>, actor<BaseB> >::composite_type + ret_t; + + return ret_t(OperationT(), _0, _1); + } + }; + +} // namespace impl + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(pop) +#endif + +} // namespace phoenix + +#endif diff --git a/boost/spirit/home/classic/phoenix/functions.hpp b/boost/spirit/home/classic/phoenix/functions.hpp new file mode 100644 index 0000000000..7e40ce958c --- /dev/null +++ b/boost/spirit/home/classic/phoenix/functions.hpp @@ -0,0 +1,760 @@ +/*============================================================================= + Phoenix V1.2.1 + Copyright (c) 2001-2002 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) +==============================================================================*/ +#ifndef PHOENIX_FUNCTIONS_HPP +#define PHOENIX_FUNCTIONS_HPP + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/spirit/home/classic/phoenix/actor.hpp> +#include <boost/spirit/home/classic/phoenix/composite.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace phoenix { + +/////////////////////////////////////////////////////////////////////////////// +// +// function class +// +// Lazy functions +// +// This class provides a mechanism for lazily evaluating functions. +// Syntactically, a lazy function looks like an ordinary C/C++ +// function. The function call looks the same. However, unlike +// ordinary functions, the actual function execution is deferred. +// (see actor.hpp, primitives.hpp and composite.hpp for an +// overview). For example here are sample factorial function calls: +// +// factorial(4) +// factorial(arg1) +// factorial(arg1 * 6) +// +// These functions are automatically lazily bound unlike ordinary +// function pointers or functor objects that need to be explicitly +// bound through the bind function (see binders.hpp). +// +// A lazy function works in conjunction with a user defined functor +// (as usual with a member operator()). Only special forms of +// functor objects are allowed. This is required to enable true +// polymorphism (STL style monomorphic functors and function +// pointers can still be used through the bind facility in +// binders.hpp). +// +// This special functor is expected to have a nested template class +// result<A...TN> (where N is the number of arguments of its +// member operator()). The nested template class result should have +// a typedef 'type' that reflects the return type of its member +// operator(). This is essentially a type computer that answers the +// metaprogramming question "Given arguments of type A...TN, what +// will be the operator()'s return type?". +// +// There is a special case for functors that accept no arguments. +// Such nullary functors are only required to define a typedef +// result_type that reflects the return type of its operator(). +// +// Here's an example of a simple functor that computes the +// factorial of a number: +// +// struct factorial_impl { +// +// template <typename Arg> +// struct result { typedef Arg type; }; +// +// template <typename Arg> +// Arg operator()(Arg n) const +// { return (n <= 0) ? 1 : n * this->operator()(n-1); } +// }; +// +// As can be seen, the functor can be polymorphic. Its arguments +// and return type are not fixed to a particular type. The example +// above for example, can handle any type as long as it can carry +// out the required operations (i.e. <=, * and -). +// +// We can now declare and instantiate a lazy 'factorial' function: +// +// function<factorial_impl> factorial; +// +// Invoking a lazy function 'factorial' does not immediately +// execute the functor factorial_impl. Instead, a composite (see +// composite.hpp) object is created and returned to the caller. +// Example: +// +// factorial(arg1) +// +// does nothing more than return a composite. A second function +// call will invoke the actual factorial function. Example: +// +// int i = 4; +// cout << factorial(arg1)(i); +// +// will print out "24". +// +// Take note that in certain cases (e.g. for functors with state), +// an instance may be passed on to the constructor. Example: +// +// function<factorial_impl> factorial(ftor); +// +// where ftor is an instance of factorial_impl (this is not +// necessary in this case since factorial is a simple stateless +// functor). Take care though when using functors with state +// because the functors are taken in by value. It is best to keep +// the data manipulated by a functor outside the functor itself and +// keep a reference to this data inside the functor. Also, it is +// best to keep functors as small as possible. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename OperationT> +struct function { + + function() : op() {} + function(OperationT const& op_) : op(op_) {} + + actor<composite<OperationT> > + operator()() const; + + template <typename A> + typename impl::make_composite<OperationT, A>::type + operator()(A const& a) const; + + template <typename A, typename B> + typename impl::make_composite<OperationT, A, B>::type + operator()(A const& a, B const& b) const; + + template <typename A, typename B, typename C> + typename impl::make_composite<OperationT, A, B, C>::type + operator()(A const& a, B const& b, C const& c) const; + +#if PHOENIX_LIMIT > 3 + + template <typename A, typename B, typename C, typename D> + typename impl::make_composite<OperationT, A, B, C, D>::type + operator()(A const& a, B const& b, C const& c, D const& d) const; + + template <typename A, typename B, typename C, typename D, typename E> + typename impl::make_composite< + OperationT, A, B, C, D, E + >::type + operator()( + A const& a, B const& b, C const& c, D const& d, E const& e + ) const; + + template < + typename A, typename B, typename C, typename D, typename E, + typename F + > + typename impl::make_composite< + OperationT, A, B, C, D, E, F + >::type + operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f + ) const; + +#if PHOENIX_LIMIT > 6 + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G + > + typename impl::make_composite< + OperationT, A, B, C, D, E, F, G + >::type + operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g + ) const; + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H + > + typename impl::make_composite< + OperationT, A, B, C, D, E, F, G, H + >::type + operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h + ) const; + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I + > + typename impl::make_composite< + OperationT, A, B, C, D, E, F, G, H, I + >::type + operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i + ) const; + +#if PHOENIX_LIMIT > 9 + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J + > + typename impl::make_composite< + OperationT, A, B, C, D, E, F, G, H, I, J + >::type + operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j + ) const; + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K + > + typename impl::make_composite< + OperationT, A, B, C, D, E, F, G, H, I, J, K + >::type + operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k + ) const; + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L + > + typename impl::make_composite< + OperationT, A, B, C, D, E, F, G, H, I, J, K, L + >::type + operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k, L const& l + ) const; + +#if PHOENIX_LIMIT > 12 + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M + > + typename impl::make_composite< + OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M + >::type + operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k, L const& l, M const& m + ) const; + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M, typename N + > + typename impl::make_composite< + OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M, N + >::type + operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k, L const& l, M const& m, N const& n + ) const; + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M, typename N, typename O + > + typename impl::make_composite< + OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O + >::type + operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k, L const& l, M const& m, N const& n, O const& o + ) const; + +#endif +#endif +#endif +#endif + + OperationT op; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// function class implementation +// +/////////////////////////////////////////////////////////////////////////////// +template <typename OperationT> +inline actor<composite<OperationT> > +function<OperationT>::operator()() const +{ + return actor<composite<OperationT> >(op); +} + +////////////////////////////////// +template <typename OperationT> +template <typename A> +inline typename impl::make_composite<OperationT, A>::type +function<OperationT>::operator()(A const& a) const +{ + typedef typename impl::make_composite<OperationT, A>::composite_type ret_t; + return ret_t + ( + op, + as_actor<A>::convert(a) + ); +} + +////////////////////////////////// +template <typename OperationT> +template <typename A, typename B> +inline typename impl::make_composite<OperationT, A, B>::type +function<OperationT>::operator()(A const& a, B const& b) const +{ + typedef + typename impl::make_composite<OperationT, A, B>::composite_type + ret_t; + + return ret_t( + op, + as_actor<A>::convert(a), + as_actor<B>::convert(b) + ); +} + +////////////////////////////////// +template <typename OperationT> +template <typename A, typename B, typename C> +inline typename impl::make_composite<OperationT, A, B, C>::type +function<OperationT>::operator()(A const& a, B const& b, C const& c) const +{ + typedef + typename impl::make_composite<OperationT, A, B, C>::composite_type + ret_t; + + return ret_t( + op, + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c) + ); +} + +#if PHOENIX_LIMIT > 3 +////////////////////////////////// +template <typename OperationT> +template < + typename A, typename B, typename C, typename D +> +inline typename impl::make_composite< + OperationT, A, B, C, D +>::type +function<OperationT>::operator()( + A const& a, B const& b, C const& c, D const& d +) const +{ + typedef typename impl::make_composite< + OperationT, A, B, C, D + >::composite_type ret_t; + + return ret_t( + op, + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c), + as_actor<D>::convert(d) + ); +} + +////////////////////////////////// +template <typename OperationT> +template < + typename A, typename B, typename C, typename D, typename E +> +inline typename impl::make_composite< + OperationT, A, B, C, D, E +>::type +function<OperationT>::operator()( + A const& a, B const& b, C const& c, D const& d, E const& e +) const +{ + typedef typename impl::make_composite< + OperationT, A, B, C, D, E + >::composite_type ret_t; + + return ret_t( + op, + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c), + as_actor<D>::convert(d), + as_actor<E>::convert(e) + ); +} + +////////////////////////////////// +template <typename OperationT> +template < + typename A, typename B, typename C, typename D, typename E, + typename F +> +inline typename impl::make_composite< + OperationT, A, B, C, D, E, F +>::type +function<OperationT>::operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f +) const +{ + typedef typename impl::make_composite< + OperationT, A, B, C, D, E, F + >::composite_type ret_t; + + return ret_t( + op, + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c), + as_actor<D>::convert(d), + as_actor<E>::convert(e), + as_actor<F>::convert(f) + ); +} + +#if PHOENIX_LIMIT > 6 + +////////////////////////////////// +template <typename OperationT> +template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G +> +inline typename impl::make_composite< + OperationT, A, B, C, D, E, F, G +>::type +function<OperationT>::operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g +) const +{ + typedef typename impl::make_composite< + OperationT, A, B, C, D, E, F, G + >::composite_type ret_t; + + return ret_t( + op, + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c), + as_actor<D>::convert(d), + as_actor<E>::convert(e), + as_actor<F>::convert(f), + as_actor<G>::convert(g) + ); +} + +////////////////////////////////// +template <typename OperationT> +template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H +> +inline typename impl::make_composite< + OperationT, A, B, C, D, E, F, G, H +>::type +function<OperationT>::operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h +) const +{ + typedef typename impl::make_composite< + OperationT, A, B, C, D, E, F, G, H + >::composite_type ret_t; + + return ret_t( + op, + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c), + as_actor<D>::convert(d), + as_actor<E>::convert(e), + as_actor<F>::convert(f), + as_actor<G>::convert(g), + as_actor<H>::convert(h) + ); +} + +////////////////////////////////// +template <typename OperationT> +template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I +> +inline typename impl::make_composite< + OperationT, A, B, C, D, E, F, G, H, I +>::type +function<OperationT>::operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i +) const +{ + typedef typename impl::make_composite< + OperationT, A, B, C, D, E, F, G, H, I + >::composite_type ret_t; + + return ret_t( + op, + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c), + as_actor<D>::convert(d), + as_actor<E>::convert(e), + as_actor<F>::convert(f), + as_actor<G>::convert(g), + as_actor<H>::convert(h), + as_actor<I>::convert(i) + ); +} + +#if PHOENIX_LIMIT > 9 + +////////////////////////////////// +template <typename OperationT> +template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J +> +inline typename impl::make_composite< + OperationT, A, B, C, D, E, F, G, H, I, J +>::type +function<OperationT>::operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j +) const +{ + typedef typename impl::make_composite< + OperationT, A, B, C, D, E, F, G, H, I, J + >::composite_type ret_t; + + return ret_t( + op, + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c), + as_actor<D>::convert(d), + as_actor<E>::convert(e), + as_actor<F>::convert(f), + as_actor<G>::convert(g), + as_actor<H>::convert(h), + as_actor<I>::convert(i), + as_actor<J>::convert(j) + ); +} + +////////////////////////////////// +template <typename OperationT> +template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K +> +inline typename impl::make_composite< + OperationT, A, B, C, D, E, F, G, H, I, J, K +>::type +function<OperationT>::operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k +) const +{ + typedef typename impl::make_composite< + OperationT, A, B, C, D, E, F, G, H, I, J, K + >::composite_type ret_t; + + return ret_t( + op, + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c), + as_actor<D>::convert(d), + as_actor<E>::convert(e), + as_actor<F>::convert(f), + as_actor<G>::convert(g), + as_actor<H>::convert(h), + as_actor<I>::convert(i), + as_actor<J>::convert(j), + as_actor<K>::convert(k) + ); +} + +////////////////////////////////// +template <typename OperationT> +template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L +> +inline typename impl::make_composite< + OperationT, A, B, C, D, E, F, G, H, I, J, K, L +>::type +function<OperationT>::operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k, L const& l +) const +{ + typedef typename impl::make_composite< + OperationT, A, B, C, D, E, F, G, H, I, J, K, L + >::composite_type ret_t; + + return ret_t( + op, + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c), + as_actor<D>::convert(d), + as_actor<E>::convert(e), + as_actor<F>::convert(f), + as_actor<G>::convert(g), + as_actor<H>::convert(h), + as_actor<I>::convert(i), + as_actor<J>::convert(j), + as_actor<K>::convert(k), + as_actor<L>::convert(l) + ); +} + +#if PHOENIX_LIMIT > 12 + +////////////////////////////////// +template <typename OperationT> +template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M +> +inline typename impl::make_composite< + OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M +>::type +function<OperationT>::operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k, L const& l, M const& m +) const +{ + typedef typename impl::make_composite< + OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M + >::composite_type ret_t; + + return ret_t( + op, + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c), + as_actor<D>::convert(d), + as_actor<E>::convert(e), + as_actor<F>::convert(f), + as_actor<G>::convert(g), + as_actor<H>::convert(h), + as_actor<I>::convert(i), + as_actor<J>::convert(j), + as_actor<K>::convert(k), + as_actor<L>::convert(l), + as_actor<M>::convert(m) + ); +} + +////////////////////////////////// +template <typename OperationT> +template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M, typename N +> +inline typename impl::make_composite< + OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M, N +>::type +function<OperationT>::operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k, L const& l, M const& m, N const& n +) const +{ + typedef typename impl::make_composite< + OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M, N + >::composite_type ret_t; + + return ret_t( + op, + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c), + as_actor<D>::convert(d), + as_actor<E>::convert(e), + as_actor<F>::convert(f), + as_actor<G>::convert(g), + as_actor<H>::convert(h), + as_actor<I>::convert(i), + as_actor<J>::convert(j), + as_actor<K>::convert(k), + as_actor<L>::convert(l), + as_actor<M>::convert(m), + as_actor<N>::convert(n) + ); +} + +////////////////////////////////// +template <typename OperationT> +template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M, typename N, typename O +> +inline typename impl::make_composite< + OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O +>::type +function<OperationT>::operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k, L const& l, M const& m, N const& n, O const& o +) const +{ + typedef typename impl::make_composite< + OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O + >::composite_type ret_t; + + return ret_t( + op, + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c), + as_actor<D>::convert(d), + as_actor<E>::convert(e), + as_actor<F>::convert(f), + as_actor<G>::convert(g), + as_actor<H>::convert(h), + as_actor<I>::convert(i), + as_actor<J>::convert(j), + as_actor<K>::convert(k), + as_actor<L>::convert(l), + as_actor<M>::convert(m), + as_actor<N>::convert(n), + as_actor<O>::convert(o) + ); +} + +#endif +#endif +#endif +#endif + +/////////////////////////////////////////////////////////////////////////////// +} // namespace phoenix + +#endif diff --git a/boost/spirit/home/classic/phoenix/new.hpp b/boost/spirit/home/classic/phoenix/new.hpp new file mode 100644 index 0000000000..f1a46366b0 --- /dev/null +++ b/boost/spirit/home/classic/phoenix/new.hpp @@ -0,0 +1,1315 @@ +/*============================================================================= + Phoenix V1.2.1 + Copyright (c) 2001-2003 Joel de Guzman + Copyright (c) 2001-2003 Hartmut Kaiser + Copyright (c) 2003 Vaclav Vesely + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#ifndef PHOENIX_NEW_HPP +#define PHOENIX_NEW_HPP + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/spirit/home/classic/phoenix/actor.hpp> +#include <boost/spirit/home/classic/phoenix/composite.hpp> +#include <boost/static_assert.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace phoenix { + +/////////////////////////////////////////////////////////////////////////////// +// +// Phoenix predefined maximum new_ limit. This limit defines the maximum +// number of parameters supported for calles to the set of new_ template +// functions (lazy object construction, see below). This number defaults to 3. +// The actual maximum is rounded up in multiples of 3. Thus, if this value +// is 4, the actual limit is 6. The ultimate maximum limit in this +// implementation is 15. +// PHOENIX_CONSTRUCT_LIMIT should NOT be greater than PHOENIX_LIMIT! + +#if !defined(PHOENIX_CONSTRUCT_LIMIT) +#define PHOENIX_CONSTRUCT_LIMIT PHOENIX_LIMIT +#endif + +// ensure PHOENIX_CONSTRUCT_LIMIT <= PHOENIX_LIMIT +BOOST_STATIC_ASSERT(PHOENIX_CONSTRUCT_LIMIT <= PHOENIX_LIMIT); + +// ensure PHOENIX_CONSTRUCT_LIMIT <= 15 +BOOST_STATIC_ASSERT(PHOENIX_CONSTRUCT_LIMIT <= 15); + +/////////////////////////////////////////////////////////////////////////////// +// +// new_ +// +// Lazy object construction +// +// The set of new_<> template classes and functions provide a way +// of lazily constructing certain object from a arbitrary set of +// actors during parsing. +// The new_ templates are (syntactically) used very much like +// the well known C++ casts: +// +// A *a = new_<A>(...arbitrary list of actors...); +// +// where the given parameters are submitted as parameters to the +// contructor of the object of type A. (This certainly implies, that +// type A has a constructor with a fitting set of parameter types +// defined.) +// +// The maximum number of needed parameters is controlled through the +// preprocessor constant PHOENIX_CONSTRUCT_LIMIT. Note though, that this +// limit should not be greater than PHOENIX_LIMIT. +// +/////////////////////////////////////////////////////////////////////////////// + +template <typename T> +struct new_l_0 +{ + typedef T* result_type; + + T* operator()() const + { + return new T(); + } +}; + +template <typename T> +struct new_l { + + template < + typename A + , typename B + , typename C + +#if PHOENIX_CONSTRUCT_LIMIT > 3 + , typename D + , typename E + , typename F + +#if PHOENIX_CONSTRUCT_LIMIT > 6 + , typename G + , typename H + , typename I + +#if PHOENIX_CONSTRUCT_LIMIT > 9 + , typename J + , typename K + , typename L + +#if PHOENIX_CONSTRUCT_LIMIT > 12 + , typename M + , typename N + , typename O +#endif +#endif +#endif +#endif + > + struct result { typedef T* type; }; + + T* operator()() const { + return new T(); + } + + template <typename A> + T* operator()(A const& a) const { + return new T(a); + } + + template <typename A, typename B> + T* operator()(A const& a, B const& b) const { + return new T(a, b); + } + + template <typename A, typename B, typename C> + T* operator()(A const& a, B const& b, C const& c) const { + return new T(a, b, c); + } + +#if PHOENIX_CONSTRUCT_LIMIT > 3 + template < + typename A, typename B, typename C, typename D + > + T* operator()( + A const& a, B const& b, C const& c, D const& d) const + { + return new T(a, b, c, d); + } + + template < + typename A, typename B, typename C, typename D, typename E + > + T* operator()( + A const& a, B const& b, C const& c, D const& d, E const& e) const + { + return new T(a, b, c, d, e); + } + + template < + typename A, typename B, typename C, typename D, typename E, + typename F + > + T* operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f) const + { + return new T(a, b, c, d, e, f); + } + +#if PHOENIX_CONSTRUCT_LIMIT > 6 + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G + > + T* operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g) const + { + return new T(a, b, c, d, e, f, g); + } + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H + > + T* operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h) const + { + return new T(a, b, c, d, e, f, g, h); + } + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I + > + T* operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i) const + { + return new T(a, b, c, d, e, f, g, h, i); + } + +#if PHOENIX_CONSTRUCT_LIMIT > 9 + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J + > + T* operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j) const + { + return new T(a, b, c, d, e, f, g, h, i, j); + } + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K + > + T* operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k) const + { + return new T(a, b, c, d, e, f, g, h, i, j, k); + } + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L + > + T* operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k, L const& l) const + { + return new T(a, b, c, d, e, f, g, h, i, j, k, l); + } + +#if PHOENIX_CONSTRUCT_LIMIT > 12 + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M + > + T* operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k, L const& l, M const& m) const + { + return new T(a, b, c, d, e, f, g, h, i, j, k, l, m); + } + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M, typename N + > + T* operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k, L const& l, M const& m, N const& n) const + { + return new T(a, b, c, d, e, f, g, h, i, j, k, l, m, n); + } + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M, typename N, typename O + > + T* operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k, L const& l, M const& m, N const& n, O const& o) const + { + return new T(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o); + } + +#endif +#endif +#endif +#endif +}; + +template <typename T> +struct new_1 { + + template < + typename A + > + struct result { typedef T* type; }; + + template <typename A> + T* operator()(A const& a) const { + return new T(a); + } + +}; + +template <typename T> +struct new_2 { + + template < + typename A + , typename B + > + struct result { typedef T* type; }; + + template <typename A, typename B> + T* operator()(A const& a, B const& b) const { + return new T(a, b); + } + +}; + +template <typename T> +struct new_3 { + + template < + typename A + , typename B + , typename C + > + struct result { typedef T* type; }; + + template <typename A, typename B, typename C> + T* operator()(A const& a, B const& b, C const& c) const { + return new T(a, b, c); + } +}; + +#if PHOENIX_CONSTRUCT_LIMIT > 3 +template <typename T> +struct new_4 { + + template < + typename A + , typename B + , typename C + , typename D + > + struct result { typedef T* type; }; + + + template < + typename A, typename B, typename C, typename D + > + T* operator()( + A const& a, B const& b, C const& c, D const& d) const + { + return new T(a, b, c, d); + } +}; + + +template <typename T> +struct new_5 { + + template < + typename A + , typename B + , typename C + , typename D + , typename E + > + struct result { typedef T* type; }; + + template < + typename A, typename B, typename C, typename D, typename E + > + T* operator()( + A const& a, B const& b, C const& c, D const& d, E const& e) const + { + return new T(a, b, c, d, e); + } +}; + + +template <typename T> +struct new_6 { + + template < + typename A + , typename B + , typename C + , typename D + , typename E + , typename F + > + struct result { typedef T* type; }; + + template < + typename A, typename B, typename C, typename D, typename E, + typename F + > + T* operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f) const + { + return new T(a, b, c, d, e, f); + } +}; +#endif + + +#if PHOENIX_CONSTRUCT_LIMIT > 6 +template <typename T> +struct new_7 { + + template < + typename A + , typename B + , typename C + , typename D + , typename E + , typename F + , typename G + > + struct result { typedef T* type; }; + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G + > + T* operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g) const + { + return new T(a, b, c, d, e, f, g); + } +}; + +template <typename T> +struct new_8 { + + template < + typename A + , typename B + , typename C + , typename D + , typename E + , typename F + , typename G + , typename H + > + struct result { typedef T* type; }; + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H + > + T* operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h) const + { + return new T(a, b, c, d, e, f, g, h); + } +}; + +template <typename T> +struct new_9 { + + template < + typename A + , typename B + , typename C + , typename D + , typename E + , typename F + , typename G + , typename H + , typename I + > + struct result { typedef T* type; }; + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I + > + T* operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i) const + { + return new T(a, b, c, d, e, f, g, h, i); + } +}; +#endif + + +#if PHOENIX_CONSTRUCT_LIMIT > 9 +template <typename T> +struct new_10 { + + template < + typename A + , typename B + , typename C + , typename D + , typename E + , typename F + , typename G + , typename H + , typename I + , typename J + > + struct result { typedef T* type; }; + + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J + > + T* operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j) const + { + return new T(a, b, c, d, e, f, g, h, i, j); + } +}; + +template <typename T> +struct new_11 { + + template < + typename A + , typename B + , typename C + , typename D + , typename E + , typename F + , typename G + , typename H + , typename I + , typename J + , typename K + > + struct result { typedef T* type; }; + + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K + > + T* operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k) const + { + return new T(a, b, c, d, e, f, g, h, i, j, k); + } + +}; + +template <typename T> +struct new_12 { + + template < + typename A + , typename B + , typename C + , typename D + , typename E + , typename F + , typename G + , typename H + , typename I + , typename J + , typename K + , typename L + > + struct result { typedef T* type; }; + + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L + > + T* operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k, L const& l) const + { + return new T(a, b, c, d, f, e, g, h, i, j, k, l); + } +}; +#endif + +#if PHOENIX_CONSTRUCT_LIMIT > 12 +template <typename T> +struct new_13 { + + template < + typename A + , typename B + , typename C + , typename D + , typename E + , typename F + , typename G + , typename H + , typename I + , typename J + , typename K + , typename L + , typename M + > + struct result { typedef T* type; }; + + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M + > + T* operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k, L const& l, M const& m) const + { + return new T(a, b, c, d, e, f, g, h, i, j, k, l, m); + } +}; + +template <typename T> +struct new_14 { + + template < + typename A + , typename B + , typename C + , typename D + , typename E + , typename F + , typename G + , typename H + , typename I + , typename J + , typename K + , typename L + , typename M + , typename N + > + struct result { typedef T* type; }; + + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M, typename N + > + T* operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k, L const& l, M const& m, N const& n) const + { + return new T(a, b, c, d, e, f, g, h, i, j, k, l, m, n); + } + +}; + +template <typename T> +struct new_15 { + + template < + typename A + , typename B + , typename C + , typename D + , typename E + , typename F + , typename G + , typename H + , typename I + , typename J + , typename K + , typename L + , typename M + , typename N + , typename O + > + struct result { typedef T* type; }; + + + template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M, typename N, typename O + > + T* operator()( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k, L const& l, M const& m, N const& n, O const& o) const + { + return new T(a, b, c, d, f, e, g, h, i, j, k, l, m, n, o); + } + +}; +#endif + + +#if defined(__BORLANDC__) || (defined(__MWERKS__) && (__MWERKS__ <= 0x3002)) + +/////////////////////////////////////////////////////////////////////////////// +// +// The following specializations are needed because Borland and CodeWarrior +// does not accept default template arguments in nested template classes in +// classes (i.e new_l::result) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename T, typename TupleT> +struct composite0_result<new_l_0<T>, TupleT> { + + typedef T* type; +}; + +////////////////////////////////// +template <typename T, typename TupleT, + typename A> +struct composite1_result<new_l<T>, TupleT, A> { + + typedef T* type; +}; + +////////////////////////////////// +template <typename T, typename TupleT, + typename A, typename B> +struct composite2_result<new_l<T>, TupleT, A, B> { + + typedef T* type; +}; + +////////////////////////////////// +template <typename T, typename TupleT, + typename A, typename B, typename C> +struct composite3_result<new_l<T>, TupleT, A, B, C> { + + typedef T* type; +}; + +#if PHOENIX_LIMIT > 3 +////////////////////////////////// +template <typename T, typename TupleT, + typename A, typename B, typename C, typename D> +struct composite4_result<new_l<T>, TupleT, + A, B, C, D> { + + typedef T* type; +}; + +////////////////////////////////// +template <typename T, typename TupleT, + typename A, typename B, typename C, typename D, typename E> +struct composite5_result<new_l<T>, TupleT, + A, B, C, D, E> { + + typedef T* type; +}; + +////////////////////////////////// +template <typename T, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F> +struct composite6_result<new_l<T>, TupleT, + A, B, C, D, E, F> { + + typedef T* type; +}; + +#if PHOENIX_LIMIT > 6 +////////////////////////////////// +template <typename T, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G> +struct composite7_result<new_l<T>, TupleT, + A, B, C, D, E, F, G> { + + typedef T* type; +}; + +////////////////////////////////// +template <typename T, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H> +struct composite8_result<new_l<T>, TupleT, + A, B, C, D, E, F, G, H> { + + typedef T* type; +}; + +////////////////////////////////// +template <typename T, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I> +struct composite9_result<new_l<T>, TupleT, + A, B, C, D, E, F, G, H, I> { + + typedef T* type; +}; + +#if PHOENIX_LIMIT > 9 +////////////////////////////////// +template <typename T, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J> +struct composite10_result<new_l<T>, TupleT, + A, B, C, D, E, F, G, H, I, J> { + + typedef T* type; +}; + +////////////////////////////////// +template <typename T, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K> +struct composite11_result<new_l<T>, TupleT, + A, B, C, D, E, F, G, H, I, J, K> { + + typedef T* type; +}; + +////////////////////////////////// +template <typename T, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L> +struct composite12_result<new_l<T>, TupleT, + A, B, C, D, E, F, G, H, I, J, K, L> { + + typedef T* type; +}; + +#if PHOENIX_LIMIT > 12 +////////////////////////////////// +template <typename T, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M> +struct composite13_result<new_l<T>, TupleT, + A, B, C, D, E, F, G, H, I, J, K, L, M> { + + typedef T* type; +}; + +////////////////////////////////// +template <typename T, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M, typename N> +struct composite14_result<new_l<T>, TupleT, + A, B, C, D, E, F, G, H, I, J, K, L, M, N> { + + typedef T* type; +}; + +////////////////////////////////// +template <typename T, typename TupleT, + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M, typename N, typename O> +struct composite15_result<new_l<T>, TupleT, + A, B, C, D, E, F, G, H, I, J, K, L, M, N, O> { + + typedef T* type; +}; + +#endif +#endif +#endif +#endif +#endif + +////////////////////////////////// +template <typename T> +inline typename impl::make_composite<new_l_0<T> >::type +new_() +{ + typedef impl::make_composite<new_l_0<T> > make_composite_t; + typedef typename make_composite_t::type type_t; + typedef typename make_composite_t::composite_type composite_type_t; + + return type_t(composite_type_t(new_l_0<T>())); +} + +////////////////////////////////// +template <typename T, typename A> +inline typename impl::make_composite<new_1<T>, A>::type +new_(A const& a) +{ + typedef impl::make_composite<new_1<T>, A> make_composite_t; + typedef typename make_composite_t::type type_t; + typedef typename make_composite_t::composite_type composite_type_t; + + return type_t(composite_type_t(new_1<T>(), + as_actor<A>::convert(a) + )); +} + +////////////////////////////////// +template <typename T, typename A, typename B> +inline typename impl::make_composite<new_2<T>, A, B>::type +new_(A const& a, B const& b) +{ + typedef impl::make_composite<new_2<T>, A, B> make_composite_t; + typedef typename make_composite_t::type type_t; + typedef typename make_composite_t::composite_type composite_type_t; + + return type_t(composite_type_t(new_2<T>(), + as_actor<A>::convert(a), + as_actor<B>::convert(b) + )); +} + +////////////////////////////////// +template <typename T, typename A, typename B, typename C> +inline typename impl::make_composite<new_3<T>, A, B, C>::type +new_(A const& a, B const& b, C const& c) +{ + typedef impl::make_composite<new_3<T>, A, B, C> make_composite_t; + typedef typename make_composite_t::type type_t; + typedef typename make_composite_t::composite_type composite_type_t; + + return type_t(composite_type_t(new_3<T>(), + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c) + )); +} + +#if PHOENIX_CONSTRUCT_LIMIT > 3 +////////////////////////////////// +template < + typename T, typename A, typename B, typename C, typename D +> +inline typename impl::make_composite<new_4<T>, A, B, C, D>::type +new_( + A const& a, B const& b, C const& c, D const& d) +{ + typedef + impl::make_composite<new_4<T>, A, B, C, D> + make_composite_t; + typedef typename make_composite_t::type type_t; + typedef typename make_composite_t::composite_type composite_type_t; + + return type_t(composite_type_t(new_4<T>(), + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c), + as_actor<D>::convert(d) + )); +} + +////////////////////////////////// +template < + typename T, typename A, typename B, typename C, typename D, typename E +> +inline typename impl::make_composite<new_5<T>, A, B, C, D, E>::type +new_( + A const& a, B const& b, C const& c, D const& d, E const& e) +{ + typedef + impl::make_composite<new_5<T>, A, B, C, D, E> + make_composite_t; + typedef typename make_composite_t::type type_t; + typedef typename make_composite_t::composite_type composite_type_t; + + return type_t(composite_type_t(new_5<T>(), + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c), + as_actor<D>::convert(d), + as_actor<E>::convert(e) + )); +} + +////////////////////////////////// +template < + typename T, typename A, typename B, typename C, typename D, typename E, + typename F +> +inline typename impl::make_composite<new_6<T>, A, B, C, D, E, F>::type +new_( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f) +{ + typedef + impl::make_composite<new_6<T>, A, B, C, D, E, F> + make_composite_t; + typedef typename make_composite_t::type type_t; + typedef typename make_composite_t::composite_type composite_type_t; + + return type_t(composite_type_t(new_6<T>(), + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c), + as_actor<D>::convert(d), + as_actor<E>::convert(e), + as_actor<F>::convert(f) + )); +} + +#if PHOENIX_CONSTRUCT_LIMIT > 6 +////////////////////////////////// +template < + typename T, typename A, typename B, typename C, typename D, typename E, + typename F, typename G +> +inline typename impl::make_composite<new_7<T>, A, B, C, D, E, F, G>::type +new_( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g) +{ + typedef + impl::make_composite<new_7<T>, A, B, C, D, E, F, G> + make_composite_t; + typedef typename make_composite_t::type type_t; + typedef typename make_composite_t::composite_type composite_type_t; + + return type_t(composite_type_t(new_7<T>(), + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c), + as_actor<D>::convert(d), + as_actor<E>::convert(e), + as_actor<F>::convert(f), + as_actor<G>::convert(g) + )); +} + +////////////////////////////////// +template < + typename T, typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H +> +inline typename impl::make_composite<new_8<T>, A, B, C, D, E, F, G, H>::type +new_( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h) +{ + typedef + impl::make_composite<new_8<T>, A, B, C, D, E, F, G, H> + make_composite_t; + typedef typename make_composite_t::type type_t; + typedef typename make_composite_t::composite_type composite_type_t; + + return type_t(composite_type_t(new_8<T>(), + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c), + as_actor<D>::convert(d), + as_actor<E>::convert(e), + as_actor<F>::convert(f), + as_actor<G>::convert(g), + as_actor<H>::convert(h) + )); +} + +////////////////////////////////// +template < + typename T, typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I +> +inline typename impl::make_composite<new_9<T>, A, B, C, D, E, F, G, H, I>::type +new_( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i) +{ + typedef + impl::make_composite<new_9<T>, A, B, C, D, E, F, G, H, I> + make_composite_t; + typedef typename make_composite_t::type type_t; + typedef typename make_composite_t::composite_type composite_type_t; + + return type_t(composite_type_t(new_9<T>(), + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c), + as_actor<D>::convert(d), + as_actor<E>::convert(e), + as_actor<F>::convert(f), + as_actor<G>::convert(g), + as_actor<H>::convert(h), + as_actor<I>::convert(i) + )); +} + +#if PHOENIX_CONSTRUCT_LIMIT > 9 +////////////////////////////////// +template < + typename T, typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J +> +inline typename impl::make_composite< + new_10<T>, A, B, C, D, E, F, G, H, I, J>::type +new_( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j) +{ + typedef + impl::make_composite< + new_10<T>, A, B, C, D, E, F, G, H, I, J + > + make_composite_t; + typedef typename make_composite_t::type type_t; + typedef typename make_composite_t::composite_type composite_type_t; + + return type_t(composite_type_t(new_10<T>(), + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c), + as_actor<D>::convert(d), + as_actor<E>::convert(e), + as_actor<F>::convert(f), + as_actor<G>::convert(g), + as_actor<H>::convert(h), + as_actor<I>::convert(i), + as_actor<J>::convert(j) + )); +} + +////////////////////////////////// +template < + typename T, typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, typename K +> +inline typename impl::make_composite< + new_11<T>, A, B, C, D, E, F, G, H, I, J, K>::type +new_( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k) +{ + typedef + impl::make_composite< + new_11<T>, A, B, C, D, E, F, G, H, I, J, K + > + make_composite_t; + typedef typename make_composite_t::type type_t; + typedef typename make_composite_t::composite_type composite_type_t; + + return type_t(composite_type_t(new_11<T>(), + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c), + as_actor<D>::convert(d), + as_actor<E>::convert(e), + as_actor<F>::convert(f), + as_actor<G>::convert(g), + as_actor<H>::convert(h), + as_actor<I>::convert(i), + as_actor<J>::convert(j), + as_actor<K>::convert(k) + )); +} + +////////////////////////////////// +template < + typename T, typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, typename K, + typename L +> +inline typename impl::make_composite< + new_12<T>, A, B, C, D, E, F, G, H, I, J, K, L>::type +new_( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k, L const& l) +{ + typedef + impl::make_composite< + new_12<T>, A, B, C, D, E, F, G, H, I, J, K, L + > + make_composite_t; + typedef typename make_composite_t::type type_t; + typedef typename make_composite_t::composite_type composite_type_t; + + return type_t(composite_type_t(new_12<T>(), + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c), + as_actor<D>::convert(d), + as_actor<E>::convert(e), + as_actor<F>::convert(f), + as_actor<G>::convert(g), + as_actor<H>::convert(h), + as_actor<I>::convert(i), + as_actor<J>::convert(j), + as_actor<K>::convert(k), + as_actor<L>::convert(l) + )); +} + +#if PHOENIX_CONSTRUCT_LIMIT > 12 +////////////////////////////////// +template < + typename T, typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, typename K, + typename L, typename M +> +inline typename impl::make_composite< + new_13<T>, A, B, C, D, E, F, G, H, I, J, K, L, M>::type +new_( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k, L const& l, M const& m) +{ + typedef + impl::make_composite< + new_13<T>, A, B, C, D, E, F, G, H, I, J, K, L, M + > + make_composite_t; + typedef typename make_composite_t::type type_t; + typedef typename make_composite_t::composite_type composite_type_t; + + return type_t(composite_type_t(new_13<T>(), + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c), + as_actor<D>::convert(d), + as_actor<E>::convert(e), + as_actor<F>::convert(f), + as_actor<G>::convert(g), + as_actor<H>::convert(h), + as_actor<I>::convert(i), + as_actor<J>::convert(j), + as_actor<K>::convert(k), + as_actor<L>::convert(l), + as_actor<M>::convert(m) + )); +} + +////////////////////////////////// +template < + typename T, typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, typename K, + typename L, typename M, typename N +> +inline typename impl::make_composite< + new_14<T>, A, B, C, D, E, F, G, H, I, J, K, L, M>::type +new_( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k, L const& l, M const& m, N const& n) +{ + typedef + impl::make_composite< + new_14<T>, A, B, C, D, E, F, G, H, I, J, K, L, M, N + > + make_composite_t; + typedef typename make_composite_t::type type_t; + typedef typename make_composite_t::composite_type composite_type_t; + + return type_t(composite_type_t(new_14<T>(), + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c), + as_actor<D>::convert(d), + as_actor<E>::convert(e), + as_actor<F>::convert(f), + as_actor<G>::convert(g), + as_actor<H>::convert(h), + as_actor<I>::convert(i), + as_actor<J>::convert(j), + as_actor<K>::convert(k), + as_actor<L>::convert(l), + as_actor<M>::convert(m), + as_actor<N>::convert(n) + )); +} + +////////////////////////////////// +template < + typename T, typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, typename K, + typename L, typename M, typename N, typename O +> +inline typename impl::make_composite< + new_15<T>, A, B, C, D, E, F, G, H, I, J, K, L, M, O>::type +new_( + A const& a, B const& b, C const& c, D const& d, E const& e, + F const& f, G const& g, H const& h, I const& i, J const& j, + K const& k, L const& l, M const& m, N const& n, O const& o) +{ + typedef + impl::make_composite< + new_15<T>, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O + > + make_composite_t; + typedef typename make_composite_t::type type_t; + typedef typename make_composite_t::composite_type composite_type_t; + + return type_t(composite_type_t(new_15<T>(), + as_actor<A>::convert(a), + as_actor<B>::convert(b), + as_actor<C>::convert(c), + as_actor<D>::convert(d), + as_actor<E>::convert(e), + as_actor<F>::convert(f), + as_actor<G>::convert(g), + as_actor<H>::convert(h), + as_actor<I>::convert(i), + as_actor<J>::convert(j), + as_actor<K>::convert(k), + as_actor<L>::convert(l), + as_actor<M>::convert(m), + as_actor<N>::convert(n), + as_actor<O>::convert(o) + )); +} + +#endif +#endif +#endif +#endif + +/////////////////////////////////////////////////////////////////////////////// +} // namespace phoenix + +#endif // PHOENIX_NEW_HPP diff --git a/boost/spirit/home/classic/phoenix/operators.hpp b/boost/spirit/home/classic/phoenix/operators.hpp new file mode 100644 index 0000000000..fa4676ceca --- /dev/null +++ b/boost/spirit/home/classic/phoenix/operators.hpp @@ -0,0 +1,2203 @@ +/*============================================================================= + Phoenix V1.2.1 + Copyright (c) 2001-2002 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) +==============================================================================*/ +#ifndef PHOENIX_OPERATORS_HPP +#define PHOENIX_OPERATORS_HPP + +/////////////////////////////////////////////////////////////////////////////// +#if !defined(BOOST_NO_CWCTYPE) + #include <cwctype> +#endif + +#if defined(__BORLANDC__) || (defined(__ICL) && __ICL >= 700) +#define CREF const& +#else +#define CREF +#endif + +#include <climits> +#include <boost/spirit/home/classic/phoenix/actor.hpp> +#include <boost/spirit/home/classic/phoenix/composite.hpp> +#include <boost/config.hpp> +#include <boost/mpl/if.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace phoenix { + +/////////////////////////////////////////////////////////////////////////////// +// +// Operators +// +// Lazy operators +// +// This class provides a mechanism for lazily evaluating operators. +// Syntactically, a lazy operator looks like an ordinary C/C++ +// infix, prefix or postfix operator. The operator application +// looks the same. However, unlike ordinary operators, the actual +// operator execution is deferred. (see actor.hpp, primitives.hpp +// and composite.hpp for an overview). Samples: +// +// arg1 + arg2 +// 1 + arg1 * arg2 +// 1 / -arg1 +// arg1 < 150 +// +// T1 set of classes implement all the C++ free operators. Like +// lazy functions (see functions.hpp), lazy operators are not +// immediately executed when invoked. Instead, a composite (see +// composite.hpp) object is created and returned to the caller. +// Example: +// +// (arg1 + arg2) * arg3 +// +// does nothing more than return a composite. T1 second function +// call will evaluate the actual operators. Example: +// +// int i = 4, j = 5, k = 6; +// cout << ((arg1 + arg2) * arg3)(i, j, k); +// +// will print out "54". +// +// Arbitrarily complex expressions can be lazily evaluated +// following three simple rules: +// +// 1) Lazy evaluated binary operators apply when at least one +// of the operands is an actor object (see actor.hpp and +// primitives.hpp). Consequently, if an operand is not an actor +// object, it is implicitly converted to an object of type +// actor<value<T> > (where T is the original type of the +// operand). +// +// 2) Lazy evaluated unary operators apply only to operands +// which are actor objects. +// +// 3) The result of a lazy operator is a composite actor object +// that can in turn apply to rule 1. +// +// Example: +// +// arg1 + 3 +// +// is a lazy expression involving the operator+. Following rule 1, +// lazy evaluation is triggered since arg1 is an instance of an +// actor<argument<N> > class (see primitives.hpp). The right +// operand <3> is implicitly converted to an actor<value<int> >. +// The result of this binary + expression is a composite object, +// following rule 3. +// +// Take note that although at least one of the operands must be a +// valid actor class in order for lazy evaluation to take effect, +// if this is not the case and we still want to lazily evaluate an +// expression, we can use var(x), val(x) or cref(x) to transform +// the operand into a valid action object (see primitives.hpp). +// Example: +// +// val(1) << 3; +// +// Supported operators: +// +// Unary operators: +// +// prefix: ~, !, -, +, ++, --, & (reference), * (dereference) +// postfix: ++, -- +// +// Binary operators: +// +// =, [], +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>= +// +, -, *, /, %, &, |, ^, <<, >> +// ==, !=, <, >, <=, >= +// &&, || +// +// Each operator has a special tag type associated with it. For +// example the binary + operator has a plus_op tag type associated +// with it. This is used to specialize either the unary_operator or +// binary_operator template classes (see unary_operator and +// binary_operator below). Specializations of these unary_operator +// and binary_operator are the actual workhorses that implement the +// operations. The behavior of each lazy operator depends on these +// unary_operator and binary_operator specializations. 'preset' +// specializations conform to the canonical operator rules modeled +// by the behavior of integers and pointers: +// +// Prefix -, + and ~ accept constant arguments and return an +// object by value. +// +// The ! accept constant arguments and returns a boolean +// result. +// +// The & (address-of), * (dereference) both return a reference +// to an object. +// +// Prefix ++ returns a reference to its mutable argument after +// it is incremented. +// +// Postfix ++ returns the mutable argument by value before it +// is incremented. +// +// The += and its family accept mutable right hand side (rhs) +// operand and return a reference to the rhs operand. +// +// Infix + and its family accept constant arguments and return +// an object by value. +// +// The == and its family accept constant arguments and return a +// boolean result. +// +// Operators && and || accept constant arguments and return a +// boolean result and are short circuit evaluated as expected. +// +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// +// Operator tags +// +// Each C++ operator has a corresponding tag type. This is +// used as a means for specializing the unary_operator and +// binary_operator (see below). The tag also serves as the +// lazy operator type compatible as a composite operation +// see (composite.hpp). +// +/////////////////////////////////////////////////////////////////////////////// + +// Unary operator tags + +struct negative_op; struct positive_op; +struct logical_not_op; struct invert_op; +struct reference_op; struct dereference_op; +struct pre_incr_op; struct pre_decr_op; +struct post_incr_op; struct post_decr_op; + +// Binary operator tags + +struct assign_op; struct index_op; +struct plus_assign_op; struct minus_assign_op; +struct times_assign_op; struct divide_assign_op; struct mod_assign_op; +struct and_assign_op; struct or_assign_op; struct xor_assign_op; +struct shift_l_assign_op; struct shift_r_assign_op; + +struct plus_op; struct minus_op; +struct times_op; struct divide_op; struct mod_op; +struct and_op; struct or_op; struct xor_op; +struct shift_l_op; struct shift_r_op; + +struct eq_op; struct not_eq_op; +struct lt_op; struct lt_eq_op; +struct gt_op; struct gt_eq_op; +struct logical_and_op; struct logical_or_op; + +/////////////////////////////////////////////////////////////////////////////// +// +// unary_operator<TagT, T> +// +// The unary_operator class implements most of the C++ unary +// operators. Each specialization is basically a simple static eval +// function plus a result_type typedef that determines the return +// type of the eval function. +// +// TagT is one of the unary operator tags above and T is the data +// type (argument) involved in the operation. +// +// Only the behavior of C/C++ built-in types are taken into account +// in the specializations provided below. For user-defined types, +// these specializations may still be used provided that the +// operator overloads of such types adhere to the standard behavior +// of built-in types. +// +// T1 separate special_ops.hpp file implements more stl savvy +// specializations. Other more specialized unary_operator +// implementations may be defined by the client for specific +// unary operator tags/data types. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename TagT, typename T> +struct unary_operator; + +////////////////////////////////// +template <typename T> +struct unary_operator<negative_op, T> { + + typedef T const result_type; + static result_type eval(T const& v) + { return -v; } +}; + +////////////////////////////////// +template <typename T> +struct unary_operator<positive_op, T> { + + typedef T const result_type; + static result_type eval(T const& v) + { return +v; } +}; + +////////////////////////////////// +template <typename T> +struct unary_operator<logical_not_op, T> { + + typedef T const result_type; + static result_type eval(T const& v) + { return !v; } +}; + +////////////////////////////////// +template <typename T> +struct unary_operator<invert_op, T> { + + typedef T const result_type; + static result_type eval(T const& v) + { return ~v; } +}; + +////////////////////////////////// +template <typename T> +struct unary_operator<reference_op, T> { + + typedef T* result_type; + static result_type eval(T& v) + { return &v; } +}; + +////////////////////////////////// +template <typename T> +struct unary_operator<dereference_op, T*> { + + typedef T& result_type; + static result_type eval(T* v) + { return *v; } +}; + +////////////////////////////////// +template <typename T> +struct unary_operator<dereference_op, T* const> { + + typedef T& result_type; + static result_type eval(T* const v) + { return *v; } +}; + +////////////////////////////////// +template <> +struct unary_operator<dereference_op, nil_t> { + + // G++ eager template instantiation + // somehow requires this. + typedef nil_t result_type; +}; + +////////////////////////////////// +#ifndef __BORLANDC__ +template <> +struct unary_operator<dereference_op, nil_t const> { + + // G++ eager template instantiation + // somehow requires this. + typedef nil_t result_type; +}; +#endif + +////////////////////////////////// +template <typename T> +struct unary_operator<pre_incr_op, T> { + + typedef T& result_type; + static result_type eval(T& v) + { return ++v; } +}; + +////////////////////////////////// +template <typename T> +struct unary_operator<pre_decr_op, T> { + + typedef T& result_type; + static result_type eval(T& v) + { return --v; } +}; + +////////////////////////////////// +template <typename T> +struct unary_operator<post_incr_op, T> { + + typedef T const result_type; + static result_type eval(T& v) + { T t(v); ++v; return t; } +}; + +////////////////////////////////// +template <typename T> +struct unary_operator<post_decr_op, T> { + + typedef T const result_type; + static result_type eval(T& v) + { T t(v); --v; return t; } +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// rank<T> +// +// rank<T> class has a static int constant 'value' that defines the +// absolute rank of a type. rank<T> is used to choose the result +// type of binary operators such as +. The type with the higher +// rank wins and is used as the operator's return type. T1 generic +// user defined type has a very high rank and always wins when +// compared against a user defined type. If this is not desireable, +// one can write a rank specialization for the type. +// +// Take note that ranks 0..9999 are reserved for the framework. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename T> +struct rank { static int const value = INT_MAX; }; + +template <> struct rank<void> { static int const value = 0; }; +template <> struct rank<bool> { static int const value = 10; }; + +template <> struct rank<char> { static int const value = 20; }; +template <> struct rank<signed char> { static int const value = 20; }; +template <> struct rank<unsigned char> { static int const value = 30; }; +#if !defined(BOOST_NO_INTRINSIC_WCHAR_T) +template <> struct rank<wchar_t> { static int const value = 40; }; +#endif // !defined(BOOST_NO_INTRINSIC_WCHAR_T) + +template <> struct rank<short> { static int const value = 50; }; +template <> struct rank<unsigned short> { static int const value = 60; }; + +template <> struct rank<int> { static int const value = 70; }; +template <> struct rank<unsigned int> { static int const value = 80; }; + +template <> struct rank<long> { static int const value = 90; }; +template <> struct rank<unsigned long> { static int const value = 100; }; + +#ifdef BOOST_HAS_LONG_LONG +template <> struct rank< ::boost::long_long_type> { static int const value = 110; }; +template <> struct rank< ::boost::ulong_long_type> { static int const value = 120; }; +#endif + +template <> struct rank<float> { static int const value = 130; }; +template <> struct rank<double> { static int const value = 140; }; +template <> struct rank<long double> { static int const value = 150; }; + +template <typename T> struct rank<T*> +{ static int const value = 160; }; + +template <typename T> struct rank<T* const> +{ static int const value = 160; }; + +template <typename T, int N> struct rank<T[N]> +{ static int const value = 160; }; + +/////////////////////////////////////////////////////////////////////////////// +// +// higher_rank<T0, T1> +// +// Chooses the type (T0 or T1) with the higher rank. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename T0, typename T1> +struct higher_rank { + typedef typename boost::mpl::if_c< + rank<T0>::value < rank<T1>::value, + T1, T0>::type type; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// binary_operator<TagT, T0, T1> +// +// The binary_operator class implements most of the C++ binary +// operators. Each specialization is basically a simple static eval +// function plus a result_type typedef that determines the return +// type of the eval function. +// +// TagT is one of the binary operator tags above T0 and T1 are the +// (arguments') data types involved in the operation. +// +// Only the behavior of C/C++ built-in types are taken into account +// in the specializations provided below. For user-defined types, +// these specializations may still be used provided that the +// operator overloads of such types adhere to the standard behavior +// of built-in types. +// +// T1 separate special_ops.hpp file implements more stl savvy +// specializations. Other more specialized unary_operator +// implementations may be defined by the client for specific +// unary operator tags/data types. +// +// All binary_operator except the logical_and_op and logical_or_op +// have an eval static function that carries out the actual operation. +// The logical_and_op and logical_or_op d are special because these +// two operators are short-circuit evaluated. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename TagT, typename T0, typename T1> +struct binary_operator; + +////////////////////////////////// +template <typename T0, typename T1> +struct binary_operator<assign_op, T0, T1> { + + typedef T0& result_type; + static result_type eval(T0& lhs, T1 const& rhs) + { return lhs = rhs; } +}; + +////////////////////////////////// +template <typename T1> +struct binary_operator<index_op, nil_t, T1> { + + // G++ eager template instantiation + // somehow requires this. + typedef nil_t result_type; +}; + +////////////////////////////////// +template <typename T0, typename T1> +struct binary_operator<index_op, T0*, T1> { + + typedef T0& result_type; + static result_type eval(T0* ptr, T1 const& index) + { return ptr[index]; } +}; + +////////////////////////////////// +template <typename T0, typename T1> +struct binary_operator<index_op, T0* const, T1> { + + typedef T0& result_type; + static result_type eval(T0* const ptr, T1 const& index) + { return ptr[index]; } +}; + +////////////////////////////////// +template <typename T0, int N, typename T1> +struct binary_operator<index_op, T0[N], T1> { + + typedef T0& result_type; + static result_type eval(T0* ptr, T1 const& index) + { return ptr[index]; } +}; + +////////////////////////////////// +template <typename T0, typename T1> +struct binary_operator<plus_assign_op, T0, T1> { + + typedef T0& result_type; + static result_type eval(T0& lhs, T1 const& rhs) + { return lhs += rhs; } +}; + +////////////////////////////////// +template <typename T0, typename T1> +struct binary_operator<minus_assign_op, T0, T1> { + + typedef T0& result_type; + static result_type eval(T0& lhs, T1 const& rhs) + { return lhs -= rhs; } +}; + +////////////////////////////////// +template <typename T0, typename T1> +struct binary_operator<times_assign_op, T0, T1> { + + typedef T0& result_type; + static result_type eval(T0& lhs, T1 const& rhs) + { return lhs *= rhs; } +}; + +////////////////////////////////// +template <typename T0, typename T1> +struct binary_operator<divide_assign_op, T0, T1> { + + typedef T0& result_type; + static result_type eval(T0& lhs, T1 const& rhs) + { return lhs /= rhs; } +}; + +////////////////////////////////// +template <typename T0, typename T1> +struct binary_operator<mod_assign_op, T0, T1> { + + typedef T0& result_type; + static result_type eval(T0& lhs, T1 const& rhs) + { return lhs %= rhs; } +}; + +////////////////////////////////// +template <typename T0, typename T1> +struct binary_operator<and_assign_op, T0, T1> { + + typedef T0& result_type; + static result_type eval(T0& lhs, T1 const& rhs) + { return lhs &= rhs; } +}; + +////////////////////////////////// +template <typename T0, typename T1> +struct binary_operator<or_assign_op, T0, T1> { + + typedef T0& result_type; + static result_type eval(T0& lhs, T1 const& rhs) + { return lhs |= rhs; } +}; + +////////////////////////////////// +template <typename T0, typename T1> +struct binary_operator<xor_assign_op, T0, T1> { + + typedef T0& result_type; + static result_type eval(T0& lhs, T1 const& rhs) + { return lhs ^= rhs; } +}; + +////////////////////////////////// +template <typename T0, typename T1> +struct binary_operator<shift_l_assign_op, T0, T1> { + + typedef T0& result_type; + static result_type eval(T0& lhs, T1 const& rhs) + { return lhs <<= rhs; } +}; + +////////////////////////////////// +template <typename T0, typename T1> +struct binary_operator<shift_r_assign_op, T0, T1> { + + typedef T0& result_type; + static result_type eval(T0& lhs, T1 const& rhs) + { return lhs >>= rhs; } +}; + +////////////////////////////////// +template <typename T0, typename T1> +struct binary_operator<plus_op, T0, T1> { + + typedef typename higher_rank<T0, T1>::type const result_type; + static result_type eval(T0 const& lhs, T1 const& rhs) + { return lhs + rhs; } +}; + +////////////////////////////////// +template <typename T0, typename T1> +struct binary_operator<minus_op, T0, T1> { + + typedef typename higher_rank<T0, T1>::type const result_type; + static result_type eval(T0 const& lhs, T1 const& rhs) + { return lhs - rhs; } +}; + +////////////////////////////////// +template <typename T0, typename T1> +struct binary_operator<times_op, T0, T1> { + + typedef typename higher_rank<T0, T1>::type const result_type; + static result_type eval(T0 const& lhs, T1 const& rhs) + { return lhs * rhs; } +}; + +////////////////////////////////// +template <typename T0, typename T1> +struct binary_operator<divide_op, T0, T1> { + + typedef typename higher_rank<T0, T1>::type const result_type; + static result_type eval(T0 const& lhs, T1 const& rhs) + { return lhs / rhs; } +}; + +////////////////////////////////// +template <typename T0, typename T1> +struct binary_operator<mod_op, T0, T1> { + + typedef typename higher_rank<T0, T1>::type const result_type; + static result_type eval(T0 const& lhs, T1 const& rhs) + { return lhs % rhs; } +}; + +////////////////////////////////// +template <typename T0, typename T1> +struct binary_operator<and_op, T0, T1> { + + typedef typename higher_rank<T0, T1>::type const result_type; + static result_type eval(T0 const& lhs, T1 const& rhs) + { return lhs & rhs; } +}; + +////////////////////////////////// +template <typename T0, typename T1> +struct binary_operator<or_op, T0, T1> { + + typedef typename higher_rank<T0, T1>::type const result_type; + static result_type eval(T0 const& lhs, T1 const& rhs) + { return lhs | rhs; } +}; + +////////////////////////////////// +template <typename T0, typename T1> +struct binary_operator<xor_op, T0, T1> { + + typedef typename higher_rank<T0, T1>::type const result_type; + static result_type eval(T0 const& lhs, T1 const& rhs) + { return lhs ^ rhs; } +}; + +////////////////////////////////// +template <typename T0, typename T1> +struct binary_operator<shift_l_op, T0, T1> { + + typedef T0 const result_type; + static result_type eval(T0 const& lhs, T1 const& rhs) + { return lhs << rhs; } +}; + +////////////////////////////////// +template <typename T0, typename T1> +struct binary_operator<shift_r_op, T0, T1> { + + typedef T0 const result_type; + static result_type eval(T0 const& lhs, T1 const& rhs) + { return lhs >> rhs; } +}; + +////////////////////////////////// +template <typename T0, typename T1> +struct binary_operator<eq_op, T0, T1> { + + typedef bool result_type; + static result_type eval(T0 const& lhs, T1 const& rhs) + { return lhs == rhs; } +}; + +////////////////////////////////// +template <typename T0, typename T1> +struct binary_operator<not_eq_op, T0, T1> { + + typedef bool result_type; + static result_type eval(T0 const& lhs, T1 const& rhs) + { return lhs != rhs; } +}; + +////////////////////////////////// +template <typename T0, typename T1> +struct binary_operator<lt_op, T0, T1> { + + typedef bool result_type; + static result_type eval(T0 const& lhs, T1 const& rhs) + { return lhs < rhs; } +}; + +////////////////////////////////// +template <typename T0, typename T1> +struct binary_operator<lt_eq_op, T0, T1> { + + typedef bool result_type; + static result_type eval(T0 const& lhs, T1 const& rhs) + { return lhs <= rhs; } +}; + +////////////////////////////////// +template <typename T0, typename T1> +struct binary_operator<gt_op, T0, T1> { + + typedef bool result_type; + static result_type eval(T0 const& lhs, T1 const& rhs) + { return lhs > rhs; } +}; + +////////////////////////////////// +template <typename T0, typename T1> +struct binary_operator<gt_eq_op, T0, T1> { + + typedef bool result_type; + static result_type eval(T0 const& lhs, T1 const& rhs) + { return lhs >= rhs; } +}; + +////////////////////////////////// +template <typename T0, typename T1> +struct binary_operator<logical_and_op, T0, T1> { + + typedef bool result_type; + // no eval function, see comment above. +}; + +////////////////////////////////// +template <typename T0, typename T1> +struct binary_operator<logical_or_op, T0, T1> { + + typedef bool result_type; + // no eval function, see comment above. +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// negative lazy operator (prefix -) +// +/////////////////////////////////////////////////////////////////////////////// +struct negative_op { + + template <typename T0> + struct result { + + typedef typename unary_operator<negative_op, T0>::result_type type; + }; + + template <typename T0> + typename unary_operator<negative_op, T0>::result_type + operator()(T0& _0) const + { return unary_operator<negative_op, T0>::eval(_0); } +}; + +////////////////////////////////// +template <typename BaseT> +inline typename impl::make_unary<negative_op, BaseT>::type +operator-(actor<BaseT> const& _0) +{ + return impl::make_unary<negative_op, BaseT>::construct(_0); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// positive lazy operator (prefix +) +// +/////////////////////////////////////////////////////////////////////////////// +struct positive_op { + + template <typename T0> + struct result { + + typedef typename unary_operator<positive_op, T0>::result_type type; + }; + + template <typename T0> + typename unary_operator<positive_op, T0>::result_type + operator()(T0& _0) const + { return unary_operator<positive_op, T0>::eval(_0); } +}; + +////////////////////////////////// +template <typename BaseT> +inline typename impl::make_unary<positive_op, BaseT>::type +operator+(actor<BaseT> const& _0) +{ + return impl::make_unary<positive_op, BaseT>::construct(_0); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// logical not lazy operator (prefix !) +// +/////////////////////////////////////////////////////////////////////////////// +struct logical_not_op { + + template <typename T0> + struct result { + + typedef typename unary_operator<logical_not_op, T0>::result_type type; + }; + + template <typename T0> + typename unary_operator<logical_not_op, T0>::result_type + operator()(T0& _0) const + { return unary_operator<logical_not_op, T0>::eval(_0); } +}; + +////////////////////////////////// +template <typename BaseT> +inline typename impl::make_unary<logical_not_op, BaseT>::type +operator!(actor<BaseT> const& _0) +{ + return impl::make_unary<logical_not_op, BaseT>::construct(_0); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// invert lazy operator (prefix ~) +// +/////////////////////////////////////////////////////////////////////////////// +struct invert_op { + + template <typename T0> + struct result { + + typedef typename unary_operator<invert_op, T0>::result_type type; + }; + + template <typename T0> + typename unary_operator<invert_op, T0>::result_type + operator()(T0& _0) const + { return unary_operator<invert_op, T0>::eval(_0); } +}; + +////////////////////////////////// +template <typename BaseT> +inline typename impl::make_unary<invert_op, BaseT>::type +operator~(actor<BaseT> const& _0) +{ + return impl::make_unary<invert_op, BaseT>::construct(_0); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// reference lazy operator (prefix &) +// +/////////////////////////////////////////////////////////////////////////////// +struct reference_op { + + template <typename T0> + struct result { + + typedef typename unary_operator<reference_op, T0>::result_type type; + }; + + template <typename T0> + typename unary_operator<reference_op, T0>::result_type + operator()(T0& _0) const + { return unary_operator<reference_op, T0>::eval(_0); } +}; + +////////////////////////////////// +template <typename BaseT> +inline typename impl::make_unary<reference_op, BaseT>::type +operator&(actor<BaseT> const& _0) +{ + return impl::make_unary<reference_op, BaseT>::construct(_0); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// dereference lazy operator (prefix *) +// +/////////////////////////////////////////////////////////////////////////////// +struct dereference_op { + + template <typename T0> + struct result { + + typedef typename unary_operator<dereference_op, T0>::result_type type; + }; + + template <typename T0> + typename unary_operator<dereference_op, T0>::result_type + operator()(T0& _0) const + { return unary_operator<dereference_op, T0>::eval(_0); } +}; + +////////////////////////////////// +template <typename BaseT> +inline typename impl::make_unary<dereference_op, BaseT>::type +operator*(actor<BaseT> const& _0) +{ + return impl::make_unary<dereference_op, BaseT>::construct(_0); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// pre increment lazy operator (prefix ++) +// +/////////////////////////////////////////////////////////////////////////////// +struct pre_incr_op { + + template <typename T0> + struct result { + + typedef typename unary_operator<pre_incr_op, T0>::result_type type; + }; + + template <typename T0> + typename unary_operator<pre_incr_op, T0>::result_type + operator()(T0& _0) const + { return unary_operator<pre_incr_op, T0>::eval(_0); } +}; + +////////////////////////////////// +template <typename BaseT> +inline typename impl::make_unary<pre_incr_op, BaseT>::type +operator++(actor<BaseT> const& _0) +{ + return impl::make_unary<pre_incr_op, BaseT>::construct(_0); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// pre decrement lazy operator (prefix --) +// +/////////////////////////////////////////////////////////////////////////////// +struct pre_decr_op { + + template <typename T0> + struct result { + + typedef typename unary_operator<pre_decr_op, T0>::result_type type; + }; + + template <typename T0> + typename unary_operator<pre_decr_op, T0>::result_type + operator()(T0& _0) const + { return unary_operator<pre_decr_op, T0>::eval(_0); } +}; + +////////////////////////////////// +template <typename BaseT> +inline typename impl::make_unary<pre_decr_op, BaseT>::type +operator--(actor<BaseT> const& _0) +{ + return impl::make_unary<pre_decr_op, BaseT>::construct(_0); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// post increment lazy operator (postfix ++) +// +/////////////////////////////////////////////////////////////////////////////// +struct post_incr_op { + + template <typename T0> + struct result { + + typedef typename unary_operator<post_incr_op, T0>::result_type type; + }; + + template <typename T0> + typename unary_operator<post_incr_op, T0>::result_type + operator()(T0& _0) const + { return unary_operator<post_incr_op, T0>::eval(_0); } +}; + +////////////////////////////////// +template <typename BaseT> +inline typename impl::make_unary<post_incr_op, BaseT>::type +operator++(actor<BaseT> const& _0, int) +{ + return impl::make_unary<post_incr_op, BaseT>::construct(_0); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// post decrement lazy operator (postfix --) +// +/////////////////////////////////////////////////////////////////////////////// +struct post_decr_op { + + template <typename T0> + struct result { + + typedef typename unary_operator<post_decr_op, T0>::result_type type; + }; + + template <typename T0> + typename unary_operator<post_decr_op, T0>::result_type + operator()(T0& _0) const + { return unary_operator<post_decr_op, T0>::eval(_0); } +}; + +////////////////////////////////// +template <typename BaseT> +inline typename impl::make_unary<post_decr_op, BaseT>::type +operator--(actor<BaseT> const& _0, int) +{ + return impl::make_unary<post_decr_op, BaseT>::construct(_0); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// assignment lazy operator (infix =) +// The acual lazy operator is a member of the actor class. +// +/////////////////////////////////////////////////////////////////////////////// +struct assign_op { + + template <typename T0, typename T1> + struct result { + + typedef typename binary_operator<assign_op, T0, T1> + ::result_type type; + }; + + template <typename T0, typename T1> + typename binary_operator<assign_op, T0, T1>::result_type + operator()(T0& _0, T1& _1) const + { return binary_operator<assign_op, T0, T1>::eval(_0, _1); } +}; + +////////////////////////////////// +template <typename BaseT> +template <typename B> +inline typename impl::make_binary1<assign_op, BaseT, B>::type +actor<BaseT>::operator=(B const& _1) const +{ + return impl::make_binary1<assign_op, BaseT, B>::construct(*this, _1); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// index lazy operator (array index []) +// The acual lazy operator is a member of the actor class. +// +/////////////////////////////////////////////////////////////////////////////// +struct index_op { + + template <typename T0, typename T1> + struct result { + + typedef typename binary_operator<index_op, T0, T1> + ::result_type type; + }; + + template <typename T0, typename T1> + typename binary_operator<index_op, T0, T1>::result_type + operator()(T0& _0, T1& _1) const + { return binary_operator<index_op, T0, T1>::eval(_0, _1); } +}; + +////////////////////////////////// +template <typename BaseT> +template <typename B> +inline typename impl::make_binary1<index_op, BaseT, B>::type +actor<BaseT>::operator[](B const& _1) const +{ + return impl::make_binary1<index_op, BaseT, B>::construct(*this, _1); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// plus assign lazy operator (infix +=) +// +/////////////////////////////////////////////////////////////////////////////// +struct plus_assign_op { + + template <typename T0, typename T1> + struct result { + + typedef typename binary_operator<plus_assign_op, T0, T1> + ::result_type type; + }; + + template <typename T0, typename T1> + typename binary_operator<plus_assign_op, T0, T1>::result_type + operator()(T0& _0, T1& _1) const + { return binary_operator<plus_assign_op, T0, T1>::eval(_0, _1); } +}; + +////////////////////////////////// +template <typename BaseT, typename T1> +inline typename impl::make_binary1<plus_assign_op, BaseT, T1>::type +operator+=(actor<BaseT> const& _0, T1 CREF _1) +{ + return impl::make_binary1<plus_assign_op, BaseT, T1>::construct(_0, _1); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// minus assign lazy operator (infix -=) +// +/////////////////////////////////////////////////////////////////////////////// +struct minus_assign_op { + + template <typename T0, typename T1> + struct result { + + typedef typename binary_operator<minus_assign_op, T0, T1> + ::result_type type; + }; + + template <typename T0, typename T1> + typename binary_operator<minus_assign_op, T0, T1>::result_type + operator()(T0& _0, T1& _1) const + { return binary_operator<minus_assign_op, T0, T1>::eval(_0, _1); } +}; + +////////////////////////////////// +template <typename BaseT, typename T1> +inline typename impl::make_binary1<minus_assign_op, BaseT, T1>::type +operator-=(actor<BaseT> const& _0, T1 CREF _1) +{ + return impl::make_binary1<minus_assign_op, BaseT, T1>::construct(_0, _1); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// times assign lazy operator (infix *=) +// +/////////////////////////////////////////////////////////////////////////////// +struct times_assign_op { + + template <typename T0, typename T1> + struct result { + + typedef typename binary_operator<times_assign_op, T0, T1> + ::result_type type; + }; + + template <typename T0, typename T1> + typename binary_operator<times_assign_op, T0, T1>::result_type + operator()(T0& _0, T1& _1) const + { return binary_operator<times_assign_op, T0, T1>::eval(_0, _1); } +}; + +////////////////////////////////// +template <typename BaseT, typename T1> +inline typename impl::make_binary1<times_assign_op, BaseT, T1>::type +operator*=(actor<BaseT> const& _0, T1 CREF _1) +{ + return impl::make_binary1<times_assign_op, BaseT, T1>::construct(_0, _1); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// divide assign lazy operator (infix /=) +// +/////////////////////////////////////////////////////////////////////////////// +struct divide_assign_op { + + template <typename T0, typename T1> + struct result { + + typedef typename binary_operator<divide_assign_op, T0, T1> + ::result_type type; + }; + + template <typename T0, typename T1> + typename binary_operator<divide_assign_op, T0, T1>::result_type + operator()(T0& _0, T1& _1) const + { return binary_operator<divide_assign_op, T0, T1>::eval(_0, _1); } +}; + +////////////////////////////////// +template <typename BaseT, typename T1> +inline typename impl::make_binary1<divide_assign_op, BaseT, T1>::type +operator/=(actor<BaseT> const& _0, T1 CREF _1) +{ + return impl::make_binary1<divide_assign_op, BaseT, T1>::construct(_0, _1); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// mod assign lazy operator (infix %=) +// +/////////////////////////////////////////////////////////////////////////////// +struct mod_assign_op { + + template <typename T0, typename T1> + struct result { + + typedef typename binary_operator<mod_assign_op, T0, T1> + ::result_type type; + }; + + template <typename T0, typename T1> + typename binary_operator<mod_assign_op, T0, T1>::result_type + operator()(T0& _0, T1& _1) const + { return binary_operator<mod_assign_op, T0, T1>::eval(_0, _1); } +}; + +////////////////////////////////// +template <typename BaseT, typename T1> +inline typename impl::make_binary1<mod_assign_op, BaseT, T1>::type +operator%=(actor<BaseT> const& _0, T1 CREF _1) +{ + return impl::make_binary1<mod_assign_op, BaseT, T1>::construct(_0, _1); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// and assign lazy operator (infix &=) +// +/////////////////////////////////////////////////////////////////////////////// +struct and_assign_op { + + template <typename T0, typename T1> + struct result { + + typedef typename binary_operator<and_assign_op, T0, T1> + ::result_type type; + }; + + template <typename T0, typename T1> + typename binary_operator<and_assign_op, T0, T1>::result_type + operator()(T0& _0, T1& _1) const + { return binary_operator<and_assign_op, T0, T1>::eval(_0, _1); } +}; + +////////////////////////////////// +template <typename BaseT, typename T1> +inline typename impl::make_binary1<and_assign_op, BaseT, T1>::type +operator&=(actor<BaseT> const& _0, T1 CREF _1) +{ + return impl::make_binary1<and_assign_op, BaseT, T1>::construct(_0, _1); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// or assign lazy operator (infix |=) +// +/////////////////////////////////////////////////////////////////////////////// +struct or_assign_op { + + template <typename T0, typename T1> + struct result { + + typedef typename binary_operator<or_assign_op, T0, T1> + ::result_type type; + }; + + template <typename T0, typename T1> + typename binary_operator<or_assign_op, T0, T1>::result_type + operator()(T0& _0, T1& _1) const + { return binary_operator<or_assign_op, T0, T1>::eval(_0, _1); } +}; + +////////////////////////////////// +template <typename BaseT, typename T1> +inline typename impl::make_binary1<or_assign_op, BaseT, T1>::type +operator|=(actor<BaseT> const& _0, T1 CREF _1) +{ + return impl::make_binary1<or_assign_op, BaseT, T1>::construct(_0, _1); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// xor assign lazy operator (infix ^=) +// +/////////////////////////////////////////////////////////////////////////////// +struct xor_assign_op { + + template <typename T0, typename T1> + struct result { + + typedef typename binary_operator<xor_assign_op, T0, T1> + ::result_type type; + }; + + template <typename T0, typename T1> + typename binary_operator<xor_assign_op, T0, T1>::result_type + operator()(T0& _0, T1& _1) const + { return binary_operator<xor_assign_op, T0, T1>::eval(_0, _1); } +}; + +////////////////////////////////// +template <typename BaseT, typename T1> +inline typename impl::make_binary1<xor_assign_op, BaseT, T1>::type +operator^=(actor<BaseT> const& _0, T1 CREF _1) +{ + return impl::make_binary1<xor_assign_op, BaseT, T1>::construct(_0, _1); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// shift left assign lazy operator (infix <<=) +// +/////////////////////////////////////////////////////////////////////////////// +struct shift_l_assign_op { + + template <typename T0, typename T1> + struct result { + + typedef typename binary_operator<shift_l_assign_op, T0, T1> + ::result_type type; + }; + + template <typename T0, typename T1> + typename binary_operator<shift_l_assign_op, T0, T1>::result_type + operator()(T0& _0, T1& _1) const + { return binary_operator<shift_l_assign_op, T0, T1>::eval(_0, _1); } +}; + +////////////////////////////////// +template <typename BaseT, typename T1> +inline typename impl::make_binary1<shift_l_assign_op, BaseT, T1>::type +operator<<=(actor<BaseT> const& _0, T1 CREF _1) +{ + return impl::make_binary1<shift_l_assign_op, BaseT, T1>::construct(_0, _1); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// shift right assign lazy operator (infix >>=) +// +/////////////////////////////////////////////////////////////////////////////// +struct shift_r_assign_op { + + template <typename T0, typename T1> + struct result { + + typedef typename binary_operator<shift_r_assign_op, T0, T1> + ::result_type type; + }; + + template <typename T0, typename T1> + typename binary_operator<shift_r_assign_op, T0, T1>::result_type + operator()(T0& _0, T1& _1) const + { return binary_operator<shift_r_assign_op, T0, T1>::eval(_0, _1); } +}; + +////////////////////////////////// +template <typename BaseT, typename T1> +inline typename impl::make_binary1<shift_r_assign_op, BaseT, T1>::type +operator>>=(actor<BaseT> const& _0, T1 CREF _1) +{ + return impl::make_binary1<shift_r_assign_op, BaseT, T1>::construct(_0, _1); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// plus lazy operator (infix +) +// +/////////////////////////////////////////////////////////////////////////////// +struct plus_op { + + template <typename T0, typename T1> + struct result { + + typedef typename binary_operator<plus_op, T0, T1> + ::result_type type; + }; + + template <typename T0, typename T1> + typename binary_operator<plus_op, T0, T1>::result_type + operator()(T0& _0, T1& _1) const + { return binary_operator<plus_op, T0, T1>::eval(_0, _1); } +}; + +////////////////////////////////// +template <typename BaseT, typename T1> +inline typename impl::make_binary1<plus_op, BaseT, T1>::type +operator+(actor<BaseT> const& _0, T1 CREF _1) +{ + return impl::make_binary1<plus_op, BaseT, T1>::construct(_0, _1); +} + +////////////////////////////////// +template <typename T0, typename BaseT> +inline typename impl::make_binary2<plus_op, T0, BaseT>::type +operator+(T0 CREF _0, actor<BaseT> const& _1) +{ + return impl::make_binary2<plus_op, T0, BaseT>::construct(_0, _1); +} + +////////////////////////////////// +template <typename BaseT0, typename BaseT1> +inline typename impl::make_binary3<plus_op, BaseT0, BaseT1>::type +operator+(actor<BaseT0> const& _0, actor<BaseT1> const& _1) +{ + return impl::make_binary3<plus_op, BaseT0, BaseT1>::construct(_0, _1); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// minus lazy operator (infix -) +// +/////////////////////////////////////////////////////////////////////////////// +struct minus_op { + + template <typename T0, typename T1> + struct result { + + typedef typename binary_operator<minus_op, T0, T1> + ::result_type type; + }; + + template <typename T0, typename T1> + typename binary_operator<minus_op, T0, T1>::result_type + operator()(T0& _0, T1& _1) const + { return binary_operator<minus_op, T0, T1>::eval(_0, _1); } +}; + +////////////////////////////////// +template <typename BaseT, typename T1> +inline typename impl::make_binary1<minus_op, BaseT, T1>::type +operator-(actor<BaseT> const& _0, T1 CREF _1) +{ + return impl::make_binary1<minus_op, BaseT, T1>::construct(_0, _1); +} + +////////////////////////////////// +template <typename T0, typename BaseT> +inline typename impl::make_binary2<minus_op, T0, BaseT>::type +operator-(T0 CREF _0, actor<BaseT> const& _1) +{ + return impl::make_binary2<minus_op, T0, BaseT>::construct(_0, _1); +} + +////////////////////////////////// +template <typename BaseT0, typename BaseT1> +inline typename impl::make_binary3<minus_op, BaseT0, BaseT1>::type +operator-(actor<BaseT0> const& _0, actor<BaseT1> const& _1) +{ + return impl::make_binary3<minus_op, BaseT0, BaseT1>::construct(_0, _1); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// times lazy operator (infix *) +// +/////////////////////////////////////////////////////////////////////////////// +struct times_op { + + template <typename T0, typename T1> + struct result { + + typedef typename binary_operator<times_op, T0, T1> + ::result_type type; + }; + + template <typename T0, typename T1> + typename binary_operator<times_op, T0, T1>::result_type + operator()(T0& _0, T1& _1) const + { return binary_operator<times_op, T0, T1>::eval(_0, _1); } +}; + +////////////////////////////////// +template <typename BaseT, typename T1> +inline typename impl::make_binary1<times_op, BaseT, T1>::type +operator*(actor<BaseT> const& _0, T1 CREF _1) +{ + return impl::make_binary1<times_op, BaseT, T1>::construct(_0, _1); +} + +////////////////////////////////// +template <typename T0, typename BaseT> +inline typename impl::make_binary2<times_op, T0, BaseT>::type +operator*(T0 CREF _0, actor<BaseT> const& _1) +{ + return impl::make_binary2<times_op, T0, BaseT>::construct(_0, _1); +} + +////////////////////////////////// +template <typename BaseT0, typename BaseT1> +inline typename impl::make_binary3<times_op, BaseT0, BaseT1>::type +operator*(actor<BaseT0> const& _0, actor<BaseT1> const& _1) +{ + return impl::make_binary3<times_op, BaseT0, BaseT1>::construct(_0, _1); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// divide lazy operator (infix /) +// +/////////////////////////////////////////////////////////////////////////////// +struct divide_op { + + template <typename T0, typename T1> + struct result { + + typedef typename binary_operator<divide_op, T0, T1> + ::result_type type; + }; + + template <typename T0, typename T1> + typename binary_operator<divide_op, T0, T1>::result_type + operator()(T0& _0, T1& _1) const + { return binary_operator<divide_op, T0, T1>::eval(_0, _1); } +}; + +////////////////////////////////// +template <typename BaseT, typename T1> +inline typename impl::make_binary1<divide_op, BaseT, T1>::type +operator/(actor<BaseT> const& _0, T1 CREF _1) +{ + return impl::make_binary1<divide_op, BaseT, T1>::construct(_0, _1); +} + +////////////////////////////////// +template <typename T0, typename BaseT> +inline typename impl::make_binary2<divide_op, T0, BaseT>::type +operator/(T0 CREF _0, actor<BaseT> const& _1) +{ + return impl::make_binary2<divide_op, T0, BaseT>::construct(_0, _1); +} + +////////////////////////////////// +template <typename BaseT0, typename BaseT1> +inline typename impl::make_binary3<divide_op, BaseT0, BaseT1>::type +operator/(actor<BaseT0> const& _0, actor<BaseT1> const& _1) +{ + return impl::make_binary3<divide_op, BaseT0, BaseT1>::construct(_0, _1); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// mod lazy operator (infix %) +// +/////////////////////////////////////////////////////////////////////////////// +struct mod_op { + + template <typename T0, typename T1> + struct result { + + typedef typename binary_operator<mod_op, T0, T1> + ::result_type type; + }; + + template <typename T0, typename T1> + typename binary_operator<mod_op, T0, T1>::result_type + operator()(T0& _0, T1& _1) const + { return binary_operator<mod_op, T0, T1>::eval(_0, _1); } +}; + +////////////////////////////////// +template <typename BaseT, typename T1> +inline typename impl::make_binary1<mod_op, BaseT, T1>::type +operator%(actor<BaseT> const& _0, T1 CREF _1) +{ + return impl::make_binary1<mod_op, BaseT, T1>::construct(_0, _1); +} + +////////////////////////////////// +template <typename T0, typename BaseT> +inline typename impl::make_binary2<mod_op, T0, BaseT>::type +operator%(T0 CREF _0, actor<BaseT> const& _1) +{ + return impl::make_binary2<mod_op, T0, BaseT>::construct(_0, _1); +} + +////////////////////////////////// +template <typename BaseT0, typename BaseT1> +inline typename impl::make_binary3<mod_op, BaseT0, BaseT1>::type +operator%(actor<BaseT0> const& _0, actor<BaseT1> const& _1) +{ + return impl::make_binary3<mod_op, BaseT0, BaseT1>::construct(_0, _1); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// and lazy operator (infix &) +// +/////////////////////////////////////////////////////////////////////////////// +struct and_op { + + template <typename T0, typename T1> + struct result { + + typedef typename binary_operator<and_op, T0, T1> + ::result_type type; + }; + + template <typename T0, typename T1> + typename binary_operator<and_op, T0, T1>::result_type + operator()(T0& _0, T1& _1) const + { return binary_operator<and_op, T0, T1>::eval(_0, _1); } +}; + +////////////////////////////////// +template <typename BaseT, typename T1> +inline typename impl::make_binary1<and_op, BaseT, T1>::type +operator&(actor<BaseT> const& _0, T1 CREF _1) +{ + return impl::make_binary1<and_op, BaseT, T1>::construct(_0, _1); +} + +////////////////////////////////// +template <typename T0, typename BaseT> +inline typename impl::make_binary2<and_op, T0, BaseT>::type +operator&(T0 CREF _0, actor<BaseT> const& _1) +{ + return impl::make_binary2<and_op, T0, BaseT>::construct(_0, _1); +} + +////////////////////////////////// +template <typename BaseT0, typename BaseT1> +inline typename impl::make_binary3<and_op, BaseT0, BaseT1>::type +operator&(actor<BaseT0> const& _0, actor<BaseT1> const& _1) +{ + return impl::make_binary3<and_op, BaseT0, BaseT1>::construct(_0, _1); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// or lazy operator (infix |) +// +/////////////////////////////////////////////////////////////////////////////// +struct or_op { + + template <typename T0, typename T1> + struct result { + + typedef typename binary_operator<or_op, T0, T1> + ::result_type type; + }; + + template <typename T0, typename T1> + typename binary_operator<or_op, T0, T1>::result_type + operator()(T0& _0, T1& _1) const + { return binary_operator<or_op, T0, T1>::eval(_0, _1); } +}; + +////////////////////////////////// +template <typename BaseT, typename T1> +inline typename impl::make_binary1<or_op, BaseT, T1>::type +operator|(actor<BaseT> const& _0, T1 CREF _1) +{ + return impl::make_binary1<or_op, BaseT, T1>::construct(_0, _1); +} + +////////////////////////////////// +template <typename T0, typename BaseT> +inline typename impl::make_binary2<or_op, T0, BaseT>::type +operator|(T0 CREF _0, actor<BaseT> const& _1) +{ + return impl::make_binary2<or_op, T0, BaseT>::construct(_0, _1); +} + +////////////////////////////////// +template <typename BaseT0, typename BaseT1> +inline typename impl::make_binary3<or_op, BaseT0, BaseT1>::type +operator|(actor<BaseT0> const& _0, actor<BaseT1> const& _1) +{ + return impl::make_binary3<or_op, BaseT0, BaseT1>::construct(_0, _1); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// xor lazy operator (infix ^) +// +/////////////////////////////////////////////////////////////////////////////// +struct xor_op { + + template <typename T0, typename T1> + struct result { + + typedef typename binary_operator<xor_op, T0, T1> + ::result_type type; + }; + + template <typename T0, typename T1> + typename binary_operator<xor_op, T0, T1>::result_type + operator()(T0& _0, T1& _1) const + { return binary_operator<xor_op, T0, T1>::eval(_0, _1); } +}; + +////////////////////////////////// +template <typename BaseT, typename T1> +inline typename impl::make_binary1<xor_op, BaseT, T1>::type +operator^(actor<BaseT> const& _0, T1 CREF _1) +{ + return impl::make_binary1<xor_op, BaseT, T1>::construct(_0, _1); +} + +////////////////////////////////// +template <typename T0, typename BaseT> +inline typename impl::make_binary2<xor_op, T0, BaseT>::type +operator^(T0 CREF _0, actor<BaseT> const& _1) +{ + return impl::make_binary2<xor_op, T0, BaseT>::construct(_0, _1); +} + +////////////////////////////////// +template <typename BaseT0, typename BaseT1> +inline typename impl::make_binary3<xor_op, BaseT0, BaseT1>::type +operator^(actor<BaseT0> const& _0, actor<BaseT1> const& _1) +{ + return impl::make_binary3<xor_op, BaseT0, BaseT1>::construct(_0, _1); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// shift left lazy operator (infix <<) +// +/////////////////////////////////////////////////////////////////////////////// +struct shift_l_op { + + template <typename T0, typename T1> + struct result { + + typedef typename binary_operator<shift_l_op, T0, T1> + ::result_type type; + }; + + template <typename T0, typename T1> + typename binary_operator<shift_l_op, T0, T1>::result_type + operator()(T0& _0, T1& _1) const + { return binary_operator<shift_l_op, T0, T1>::eval(_0, _1); } +}; + +////////////////////////////////// +template <typename BaseT, typename T1> +inline typename impl::make_binary1<shift_l_op, BaseT, T1>::type +operator<<(actor<BaseT> const& _0, T1 CREF _1) +{ + return impl::make_binary1<shift_l_op, BaseT, T1>::construct(_0, _1); +} + +////////////////////////////////// +template <typename T0, typename BaseT> +inline typename impl::make_binary2<shift_l_op, T0, BaseT>::type +operator<<(T0 CREF _0, actor<BaseT> const& _1) +{ + return impl::make_binary2<shift_l_op, T0, BaseT>::construct(_0, _1); +} + +////////////////////////////////// +template <typename BaseT0, typename BaseT1> +inline typename impl::make_binary3<shift_l_op, BaseT0, BaseT1>::type +operator<<(actor<BaseT0> const& _0, actor<BaseT1> const& _1) +{ + return impl::make_binary3<shift_l_op, BaseT0, BaseT1>::construct(_0, _1); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// shift right lazy operator (infix >>) +// +/////////////////////////////////////////////////////////////////////////////// +struct shift_r_op { + + template <typename T0, typename T1> + struct result { + + typedef typename binary_operator<shift_r_op, T0, T1> + ::result_type type; + }; + + template <typename T0, typename T1> + typename binary_operator<shift_r_op, T0, T1>::result_type + operator()(T0& _0, T1& _1) const + { return binary_operator<shift_r_op, T0, T1>::eval(_0, _1); } +}; + +////////////////////////////////// +template <typename BaseT, typename T1> +inline typename impl::make_binary1<shift_r_op, BaseT, T1>::type +operator>>(actor<BaseT> const& _0, T1 CREF _1) +{ + return impl::make_binary1<shift_r_op, BaseT, T1>::construct(_0, _1); +} + +////////////////////////////////// +template <typename T0, typename BaseT> +inline typename impl::make_binary2<shift_r_op, T0, BaseT>::type +operator>>(T0 CREF _0, actor<BaseT> const& _1) +{ + return impl::make_binary2<shift_r_op, T0, BaseT>::construct(_0, _1); +} + +////////////////////////////////// +template <typename BaseT0, typename BaseT1> +inline typename impl::make_binary3<shift_r_op, BaseT0, BaseT1>::type +operator>>(actor<BaseT0> const& _0, actor<BaseT1> const& _1) +{ + return impl::make_binary3<shift_r_op, BaseT0, BaseT1>::construct(_0, _1); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// equal lazy operator (infix ==) +// +/////////////////////////////////////////////////////////////////////////////// +struct eq_op { + + template <typename T0, typename T1> + struct result { + + typedef typename binary_operator<eq_op, T0, T1> + ::result_type type; + }; + + template <typename T0, typename T1> + typename binary_operator<eq_op, T0, T1>::result_type + operator()(T0& _0, T1& _1) const + { return binary_operator<eq_op, T0, T1>::eval(_0, _1); } +}; + +////////////////////////////////// +template <typename BaseT, typename T1> +inline typename impl::make_binary1<eq_op, BaseT, T1>::type +operator==(actor<BaseT> const& _0, T1 CREF _1) +{ + return impl::make_binary1<eq_op, BaseT, T1>::construct(_0, _1); +} + +////////////////////////////////// +template <typename T0, typename BaseT> +inline typename impl::make_binary2<eq_op, T0, BaseT>::type +operator==(T0 CREF _0, actor<BaseT> const& _1) +{ + return impl::make_binary2<eq_op, T0, BaseT>::construct(_0, _1); +} + +////////////////////////////////// +template <typename BaseT0, typename BaseT1> +inline typename impl::make_binary3<eq_op, BaseT0, BaseT1>::type +operator==(actor<BaseT0> const& _0, actor<BaseT1> const& _1) +{ + return impl::make_binary3<eq_op, BaseT0, BaseT1>::construct(_0, _1); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// not equal lazy operator (infix !=) +// +/////////////////////////////////////////////////////////////////////////////// +struct not_eq_op { + + template <typename T0, typename T1> + struct result { + + typedef typename binary_operator<not_eq_op, T0, T1> + ::result_type type; + }; + + template <typename T0, typename T1> + typename binary_operator<not_eq_op, T0, T1>::result_type + operator()(T0& _0, T1& _1) const + { return binary_operator<not_eq_op, T0, T1>::eval(_0, _1); } +}; + +////////////////////////////////// +template <typename BaseT, typename T1> +inline typename impl::make_binary1<not_eq_op, BaseT, T1>::type +operator!=(actor<BaseT> const& _0, T1 CREF _1) +{ + return impl::make_binary1<not_eq_op, BaseT, T1>::construct(_0, _1); +} + +////////////////////////////////// +template <typename T0, typename BaseT> +inline typename impl::make_binary2<not_eq_op, T0, BaseT>::type +operator!=(T0 CREF _0, actor<BaseT> const& _1) +{ + return impl::make_binary2<not_eq_op, T0, BaseT>::construct(_0, _1); +} + +////////////////////////////////// +template <typename BaseT0, typename BaseT1> +inline typename impl::make_binary3<not_eq_op, BaseT0, BaseT1>::type +operator!=(actor<BaseT0> const& _0, actor<BaseT1> const& _1) +{ + return impl::make_binary3<not_eq_op, BaseT0, BaseT1>::construct(_0, _1); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// less than lazy operator (infix <) +// +/////////////////////////////////////////////////////////////////////////////// +struct lt_op { + + template <typename T0, typename T1> + struct result { + + typedef typename binary_operator<lt_op, T0, T1> + ::result_type type; + }; + + template <typename T0, typename T1> + typename binary_operator<lt_op, T0, T1>::result_type + operator()(T0& _0, T1& _1) const + { return binary_operator<lt_op, T0, T1>::eval(_0, _1); } +}; + +////////////////////////////////// +template <typename BaseT, typename T1> +inline typename impl::make_binary1<lt_op, BaseT, T1>::type +operator<(actor<BaseT> const& _0, T1 CREF _1) +{ + return impl::make_binary1<lt_op, BaseT, T1>::construct(_0, _1); +} + +////////////////////////////////// +template <typename T0, typename BaseT> +inline typename impl::make_binary2<lt_op, T0, BaseT>::type +operator<(T0 CREF _0, actor<BaseT> const& _1) +{ + return impl::make_binary2<lt_op, T0, BaseT>::construct(_0, _1); +} + +////////////////////////////////// +template <typename BaseT0, typename BaseT1> +inline typename impl::make_binary3<lt_op, BaseT0, BaseT1>::type +operator<(actor<BaseT0> const& _0, actor<BaseT1> const& _1) +{ + return impl::make_binary3<lt_op, BaseT0, BaseT1>::construct(_0, _1); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// less than equal lazy operator (infix <=) +// +/////////////////////////////////////////////////////////////////////////////// +struct lt_eq_op { + + template <typename T0, typename T1> + struct result { + + typedef typename binary_operator<lt_eq_op, T0, T1> + ::result_type type; + }; + + template <typename T0, typename T1> + typename binary_operator<lt_eq_op, T0, T1>::result_type + operator()(T0& _0, T1& _1) const + { return binary_operator<lt_eq_op, T0, T1>::eval(_0, _1); } +}; + +////////////////////////////////// +template <typename BaseT, typename T1> +inline typename impl::make_binary1<lt_eq_op, BaseT, T1>::type +operator<=(actor<BaseT> const& _0, T1 CREF _1) +{ + return impl::make_binary1<lt_eq_op, BaseT, T1>::construct(_0, _1); +} + +////////////////////////////////// +template <typename T0, typename BaseT> +inline typename impl::make_binary2<lt_eq_op, T0, BaseT>::type +operator<=(T0 CREF _0, actor<BaseT> const& _1) +{ + return impl::make_binary2<lt_eq_op, T0, BaseT>::construct(_0, _1); +} + +////////////////////////////////// +template <typename BaseT0, typename BaseT1> +inline typename impl::make_binary3<lt_eq_op, BaseT0, BaseT1>::type +operator<=(actor<BaseT0> const& _0, actor<BaseT1> const& _1) +{ + return impl::make_binary3<lt_eq_op, BaseT0, BaseT1>::construct(_0, _1); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// greater than lazy operator (infix >) +// +/////////////////////////////////////////////////////////////////////////////// +struct gt_op { + + template <typename T0, typename T1> + struct result { + + typedef typename binary_operator<gt_op, T0, T1> + ::result_type type; + }; + + template <typename T0, typename T1> + typename binary_operator<gt_op, T0, T1>::result_type + operator()(T0& _0, T1& _1) const + { return binary_operator<gt_op, T0, T1>::eval(_0, _1); } +}; + +////////////////////////////////// +template <typename BaseT, typename T1> +inline typename impl::make_binary1<gt_op, BaseT, T1>::type +operator>(actor<BaseT> const& _0, T1 CREF _1) +{ + return impl::make_binary1<gt_op, BaseT, T1>::construct(_0, _1); +} + +////////////////////////////////// +template <typename T0, typename BaseT> +inline typename impl::make_binary2<gt_op, T0, BaseT>::type +operator>(T0 CREF _0, actor<BaseT> const& _1) +{ + return impl::make_binary2<gt_op, T0, BaseT>::construct(_0, _1); +} + +////////////////////////////////// +template <typename BaseT0, typename BaseT1> +inline typename impl::make_binary3<gt_op, BaseT0, BaseT1>::type +operator>(actor<BaseT0> const& _0, actor<BaseT1> const& _1) +{ + return impl::make_binary3<gt_op, BaseT0, BaseT1>::construct(_0, _1); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// greater than equal lazy operator (infix >=) +// +/////////////////////////////////////////////////////////////////////////////// +struct gt_eq_op { + + template <typename T0, typename T1> + struct result { + + typedef typename binary_operator<gt_eq_op, T0, T1> + ::result_type type; + }; + + template <typename T0, typename T1> + typename binary_operator<gt_eq_op, T0, T1>::result_type + operator()(T0& _0, T1& _1) const + { return binary_operator<gt_eq_op, T0, T1>::eval(_0, _1); } +}; + +////////////////////////////////// +template <typename BaseT, typename T1> +inline typename impl::make_binary1<gt_eq_op, BaseT, T1>::type +operator>=(actor<BaseT> const& _0, T1 CREF _1) +{ + return impl::make_binary1<gt_eq_op, BaseT, T1>::construct(_0, _1); +} + +////////////////////////////////// +template <typename T0, typename BaseT> +inline typename impl::make_binary2<gt_eq_op, T0, BaseT>::type +operator>=(T0 CREF _0, actor<BaseT> const& _1) +{ + return impl::make_binary2<gt_eq_op, T0, BaseT>::construct(_0, _1); +} + +////////////////////////////////// +template <typename BaseT0, typename BaseT1> +inline typename impl::make_binary3<gt_eq_op, BaseT0, BaseT1>::type +operator>=(actor<BaseT0> const& _0, actor<BaseT1> const& _1) +{ + return impl::make_binary3<gt_eq_op, BaseT0, BaseT1>::construct(_0, _1); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// logical and lazy operator (infix &&) +// +// The logical_and_composite class and its corresponding generators are +// provided to allow short-circuit evaluation of the operator's +// operands. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename A0, typename A1> +struct logical_and_composite { + + typedef logical_and_composite<A0, A1> self_t; + + template <typename TupleT> + struct result { + + typedef typename binary_operator<logical_and_op, + typename actor_result<A0, TupleT>::plain_type, + typename actor_result<A1, TupleT>::plain_type + >::result_type type; + }; + + logical_and_composite(A0 const& _0, A1 const& _1) + : a0(_0), a1(_1) {} + + template <typename TupleT> + typename actor_result<self_t, TupleT>::type + eval(TupleT const& args) const + { + return a0.eval(args) && a1.eval(args); + } + + A0 a0; A1 a1; // actors +}; + +#if !(defined(__ICL) && __ICL <= 500) +////////////////////////////////// +template <typename BaseT, typename T1> +inline actor<logical_and_composite +<actor<BaseT>, typename as_actor<T1>::type> > +operator&&(actor<BaseT> const& _0, T1 CREF _1) +{ + return logical_and_composite + <actor<BaseT>, typename as_actor<T1>::type> + (_0, as_actor<T1>::convert(_1)); +} + +////////////////////////////////// +template <typename T0, typename BaseT> +inline actor<logical_and_composite +<typename as_actor<T0>::type, actor<BaseT> > > +operator&&(T0 CREF _0, actor<BaseT> const& _1) +{ + return logical_and_composite + <typename as_actor<T0>::type, actor<BaseT> > + (as_actor<T0>::convert(_0), _1); +} + +////////////////////////////////// +template <typename BaseT0, typename BaseT1> +inline actor<logical_and_composite +<actor<BaseT0>, actor<BaseT1> > > +operator&&(actor<BaseT0> const& _0, actor<BaseT1> const& _1) +{ + return logical_and_composite + <actor<BaseT0>, actor<BaseT1> > + (_0, _1); +} +#else +////////////////////////////////// +template <typename T0, typename T1> +inline actor<logical_and_composite +<typename as_actor<T0>::type, typename as_actor<T1>::type> > +operator&&(T0 CREF _0, T1 CREF _1) +{ + return logical_and_composite + <typename as_actor<T0>::type, typename as_actor<T1>::type> + (as_actor<T0>::convert(_0), as_actor<T1>::convert(_1)); +} +#endif // !(__ICL && __ICL <= 500) + +/////////////////////////////////////////////////////////////////////////////// +// +// logical or lazy operator (infix ||) +// +// The logical_or_composite class and its corresponding generators are +// provided to allow short-circuit evaluation of the operator's +// operands. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename A0, typename A1> +struct logical_or_composite { + + typedef logical_or_composite<A0, A1> self_t; + + template <typename TupleT> + struct result { + + typedef typename binary_operator<logical_or_op, + typename actor_result<A0, TupleT>::plain_type, + typename actor_result<A1, TupleT>::plain_type + >::result_type type; + }; + + logical_or_composite(A0 const& _0, A1 const& _1) + : a0(_0), a1(_1) {} + + template <typename TupleT> + typename actor_result<self_t, TupleT>::type + eval(TupleT const& args) const + { + return a0.eval(args) || a1.eval(args); + } + + A0 a0; A1 a1; // actors +}; + +////////////////////////////////// +template <typename BaseT, typename T1> +inline actor<logical_or_composite +<actor<BaseT>, typename as_actor<T1>::type> > +operator||(actor<BaseT> const& _0, T1 CREF _1) +{ + return logical_or_composite + <actor<BaseT>, typename as_actor<T1>::type> + (_0, as_actor<T1>::convert(_1)); +} + +////////////////////////////////// +template <typename T0, typename BaseT> +inline actor<logical_or_composite +<typename as_actor<T0>::type, actor<BaseT> > > +operator||(T0 CREF _0, actor<BaseT> const& _1) +{ + return logical_or_composite + <typename as_actor<T0>::type, actor<BaseT> > + (as_actor<T0>::convert(_0), _1); +} + +////////////////////////////////// +template <typename BaseT0, typename BaseT1> +inline actor<logical_or_composite +<actor<BaseT0>, actor<BaseT1> > > +operator||(actor<BaseT0> const& _0, actor<BaseT1> const& _1) +{ + return logical_or_composite + <actor<BaseT0>, actor<BaseT1> > + (_0, _1); +} + +} // namespace phoenix + +#undef CREF +#endif diff --git a/boost/spirit/home/classic/phoenix/primitives.hpp b/boost/spirit/home/classic/phoenix/primitives.hpp new file mode 100644 index 0000000000..32dd5b96e3 --- /dev/null +++ b/boost/spirit/home/classic/phoenix/primitives.hpp @@ -0,0 +1,256 @@ +/*============================================================================= + Phoenix V1.2.1 + Copyright (c) 2001-2002 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) +==============================================================================*/ +#ifndef PHOENIX_PRIMITIVES_HPP +#define PHOENIX_PRIMITIVES_HPP + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/spirit/home/classic/phoenix/actor.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace phoenix { + +/////////////////////////////////////////////////////////////////////////////// +// +// argument class +// +// Lazy arguments +// +// An actor base class that extracts and returns the Nth argument +// from the argument list passed in the 'args' tuple in the eval +// member function (see actor.hpp). There are some predefined +// argument constants that can be used as actors (arg1..argN). +// +// The argument actor is a place-holder for the actual arguments +// passed by the client. For example, wherever arg1 is seen placed +// in a lazy function (see functions.hpp) or lazy operator (see +// operators.hpp), this will be replaced by the actual first +// argument in the actual function evaluation. Argument actors are +// essentially lazy arguments. A lazy argument is a full actor in +// its own right and can be evaluated through the actor's operator(). +// +// Example: +// +// char c = 'A'; +// int i = 123; +// const char* s = "Hello World"; +// +// cout << arg1(c) << ' '; +// cout << arg1(i, s) << ' '; +// cout << arg2(i, s) << ' '; +// +// will print out "A 123 Hello World" +// +/////////////////////////////////////////////////////////////////////////////// +template <int N> +struct argument { + + template <typename TupleT> + struct result { typedef typename tuple_element<N, TupleT>::type type; }; + + template <typename TupleT> + typename tuple_element<N, TupleT>::type + eval(TupleT const& args) const + { + return args[tuple_index<N>()]; + } +}; + +////////////////////////////////// +actor<argument<0> > const arg1 = argument<0>(); +actor<argument<1> > const arg2 = argument<1>(); +actor<argument<2> > const arg3 = argument<2>(); + +#if PHOENIX_LIMIT > 3 +actor<argument<3> > const arg4 = argument<3>(); +actor<argument<4> > const arg5 = argument<4>(); +actor<argument<5> > const arg6 = argument<5>(); + +#if PHOENIX_LIMIT > 6 +actor<argument<6> > const arg7 = argument<6>(); +actor<argument<7> > const arg8 = argument<7>(); +actor<argument<8> > const arg9 = argument<8>(); + +#if PHOENIX_LIMIT > 9 +actor<argument<9> > const arg10 = argument<9>(); +actor<argument<10> > const arg11 = argument<10>(); +actor<argument<11> > const arg12 = argument<11>(); + +#if PHOENIX_LIMIT > 12 +actor<argument<12> > const arg13 = argument<12>(); +actor<argument<13> > const arg14 = argument<13>(); +actor<argument<14> > const arg15 = argument<14>(); + +#endif +#endif +#endif +#endif +/////////////////////////////////////////////////////////////////////////////// +// +// value class +// +// Lazy values +// +// A bound actual parameter is kept in a value class for deferred +// access later when needed. A value object is immutable. Value +// objects are typically created through the val(x) free function +// which returns a value<T> with T deduced from the type of x. x is +// held in the value<T> object by value. +// +// Lazy values are actors. As such, lazy values can be evaluated +// through the actor's operator(). Such invocation gives the value's +// identity. Example: +// +// cout << val(3)() << val("Hello World")(); +// +// prints out "3 Hello World" +// +/////////////////////////////////////////////////////////////////////////////// +template <typename T> +struct value { + + typedef typename boost::remove_reference<T>::type plain_t; + + template <typename TupleT> + struct result { typedef plain_t const type; }; + + value(plain_t val_) + : val(val_) {} + + template <typename TupleT> + plain_t const + eval(TupleT const& /*args*/) const + { + return val; + } + + plain_t val; +}; + +////////////////////////////////// +template <typename T> +inline actor<value<T> > const +val(T v) +{ + return value<T>(v); +} + +////////////////////////////////// +template <typename BaseT> +void +val(actor<BaseT> const& v); // This is undefined and not allowed. + +/////////////////////////////////////////////////////////////////////////// +// +// Arbitrary types T are typically converted to a actor<value<T> > +// (see as_actor<T> in actor.hpp). A specialization is also provided +// for arrays. T[N] arrays are converted to actor<value<T const*> >. +// +/////////////////////////////////////////////////////////////////////////// +template <typename T> +struct as_actor { + + typedef actor<value<T> > type; + static type convert(T const& x) + { return value<T>(x); } +}; + +////////////////////////////////// +template <typename T, int N> +struct as_actor<T[N]> { + + typedef actor<value<T const*> > type; + static type convert(T const x[N]) + { return value<T const*>(x); } +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// variable class +// +// Lazy variables +// +// A bound actual parameter may also be held by non-const reference +// in a variable class for deferred access later when needed. A +// variable object is mutable, i.e. its referenced variable can be +// modified. Variable objects are typically created through the +// var(x) free function which returns a variable<T> with T deduced +// from the type of x. x is held in the value<T> object by +// reference. +// +// Lazy variables are actors. As such, lazy variables can be +// evaluated through the actor's operator(). Such invocation gives +// the variables's identity. Example: +// +// int i = 3; +// char const* s = "Hello World"; +// cout << var(i)() << var(s)(); +// +// prints out "3 Hello World" +// +// Another free function const_(x) may also be used. const_(x) creates +// a variable<T const&> object using a constant reference. +// +/////////////////////////////////////////////////////////////////////////////// +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(push) +#pragma warning(disable:4512) //assignment operator could not be generated +#endif + +template <typename T> +struct variable { + + template <typename TupleT> + struct result { typedef T& type; }; + + variable(T& var_) + : var(var_) {} + + template <typename TupleT> + T& + eval(TupleT const& /*args*/) const + { + return var; + } + + T& var; +}; + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(pop) +#endif + +////////////////////////////////// +template <typename T> +inline actor<variable<T> > const +var(T& v) +{ + return variable<T>(v); +} + +////////////////////////////////// +template <typename T> +inline actor<variable<T const> > const +const_(T const& v) +{ + return variable<T const>(v); +} + +////////////////////////////////// +template <typename BaseT> +void +var(actor<BaseT> const& v); // This is undefined and not allowed. + +////////////////////////////////// +template <typename BaseT> +void +const_(actor<BaseT> const& v); // This is undefined and not allowed. + +/////////////////////////////////////////////////////////////////////////////// +} // namespace phoenix + +#endif diff --git a/boost/spirit/home/classic/phoenix/special_ops.hpp b/boost/spirit/home/classic/phoenix/special_ops.hpp new file mode 100644 index 0000000000..7fc2f6d78d --- /dev/null +++ b/boost/spirit/home/classic/phoenix/special_ops.hpp @@ -0,0 +1,341 @@ +/*============================================================================= + Phoenix V1.2.1 + Copyright (c) 2001-2002 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) +==============================================================================*/ +#ifndef PHOENIX_SPECIAL_OPS_HPP +#define PHOENIX_SPECIAL_OPS_HPP + +#include <boost/config.hpp> +#ifdef BOOST_NO_STRINGSTREAM +#include <strstream> +#define PHOENIX_SSTREAM strstream +#else +#include <sstream> +#define PHOENIX_SSTREAM stringstream +#endif + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/spirit/home/classic/phoenix/operators.hpp> +#include <iosfwd> + +/////////////////////////////////////////////////////////////////////////////// +#if defined(_STLPORT_VERSION) && defined(__STL_USE_OWN_NAMESPACE) +#define PHOENIX_STD _STLP_STD +#define PHOENIX_NO_STD_NAMESPACE +#else +#define PHOENIX_STD std +#endif + +/////////////////////////////////////////////////////////////////////////////// +//#if !defined(PHOENIX_NO_STD_NAMESPACE) +namespace PHOENIX_STD +{ +//#endif + + template<typename T> class complex; + +//#if !defined(PHOENIX_NO_STD_NAMESPACE) +} +//#endif + +/////////////////////////////////////////////////////////////////////////////// +namespace phoenix +{ + +/////////////////////////////////////////////////////////////////////////////// +// +// The following specializations take into account the C++ standard +// library components. There are a couple of issues that have to be +// dealt with to enable lazy operator overloads for the standard +// library classes. +// +// *iostream (e.g. cout, cin, strstream/ stringstream) uses non- +// canonical shift operator overloads where the lhs is taken in +// by reference. +// +// *I/O manipulators overloads for the RHS of the << and >> +// operators. +// +// *STL iterators can be objects that conform to pointer semantics. +// Some operators need to be specialized for these. +// +// *std::complex is given a rank (see rank class in operators.hpp) +// +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// +// specialization for rank<std::complex> +// +/////////////////////////////////////////////////////////////////////////////// +template <typename T> struct rank<PHOENIX_STD::complex<T> > +{ static int const value = 170 + rank<T>::value; }; + +/////////////////////////////////////////////////////////////////////////////// +// +// specializations for std::istream +// +/////////////////////////////////////////////////////////////////////////////// +#if defined(__GNUC__) && (__GNUC__ < 3) + #if defined(_STLPORT_VERSION) + #define PHOENIX_ISTREAM _IO_istream_withassign + #else + #define PHOENIX_ISTREAM PHOENIX_STD::_IO_istream_withassign + #endif +#else +// #if (defined(__ICL) && defined(_STLPORT_VERSION)) +// #define PHOENIX_ISTREAM istream_withassign +// #else + #define PHOENIX_ISTREAM PHOENIX_STD::istream +// #endif +#endif + +////////////////////////////////// +#if defined(__GNUC__) && (__GNUC__ < 3) +// || (defined(__ICL) && defined(_STLPORT_VERSION)) +template <typename T1> +struct binary_operator<shift_r_op, PHOENIX_ISTREAM, T1> +{ + typedef PHOENIX_STD::istream& result_type; + static result_type eval(PHOENIX_STD::istream& out, T1& rhs) + { return out >> rhs; } +}; +#endif + +////////////////////////////////// +template <typename T1> +struct binary_operator<shift_r_op, PHOENIX_STD::istream, T1> +{ + typedef PHOENIX_STD::istream& result_type; + static result_type eval(PHOENIX_STD::istream& out, T1& rhs) + { return out >> rhs; } +}; + +////////////////////////////////// +template <typename BaseT> +inline typename impl::make_binary3 + <shift_r_op, variable<PHOENIX_ISTREAM>, BaseT>::type +operator>>(PHOENIX_ISTREAM& _0, actor<BaseT> const& _1) +{ + return impl::make_binary3 + <shift_r_op, variable<PHOENIX_ISTREAM>, BaseT> + ::construct(var(_0), _1); +} + +#undef PHOENIX_ISTREAM +/////////////////////////////////////////////////////////////////////////////// +// +// specializations for std::ostream +// +/////////////////////////////////////////////////////////////////////////////// +#if defined(__GNUC__) && (__GNUC__ < 3) + #if defined(_STLPORT_VERSION) + #define PHOENIX_OSTREAM _IO_ostream_withassign + #else + #define PHOENIX_OSTREAM PHOENIX_STD::_IO_ostream_withassign + #endif +#else +// #if (defined(__ICL) && defined(_STLPORT_VERSION)) +// #define PHOENIX_OSTREAM ostream_withassign +// #else + #define PHOENIX_OSTREAM PHOENIX_STD::ostream +// #endif +#endif + +////////////////////////////////// +#if defined(__GNUC__) && (__GNUC__ < 3) +// || (defined(__ICL) && defined(_STLPORT_VERSION)) +template <typename T1> +struct binary_operator<shift_l_op, PHOENIX_OSTREAM, T1> +{ + typedef PHOENIX_STD::ostream& result_type; + static result_type eval(PHOENIX_STD::ostream& out, T1 const& rhs) + { return out << rhs; } +}; +#endif + +////////////////////////////////// +template <typename T1> +struct binary_operator<shift_l_op, PHOENIX_STD::ostream, T1> +{ + typedef PHOENIX_STD::ostream& result_type; + static result_type eval(PHOENIX_STD::ostream& out, T1 const& rhs) + { return out << rhs; } +}; + +////////////////////////////////// +template <typename BaseT> +inline typename impl::make_binary3 + <shift_l_op, variable<PHOENIX_OSTREAM>, BaseT>::type +operator<<(PHOENIX_OSTREAM& _0, actor<BaseT> const& _1) +{ + return impl::make_binary3 + <shift_l_op, variable<PHOENIX_OSTREAM>, BaseT> + ::construct(var(_0), _1); +} + +#undef PHOENIX_OSTREAM + +/////////////////////////////////////////////////////////////////////////////// +// +// specializations for std::strstream / stringstream +// +/////////////////////////////////////////////////////////////////////////////// +template <typename T1> +struct binary_operator<shift_r_op, PHOENIX_STD::PHOENIX_SSTREAM, T1> +{ + typedef PHOENIX_STD::istream& result_type; + static result_type eval(PHOENIX_STD::istream& out, T1& rhs) + { return out >> rhs; } +}; + +////////////////////////////////// +template <typename BaseT> +inline typename impl::make_binary3 + <shift_r_op, variable<PHOENIX_STD::PHOENIX_SSTREAM>, BaseT>::type +operator>>(PHOENIX_STD::PHOENIX_SSTREAM& _0, actor<BaseT> const& _1) +{ + return impl::make_binary3 + <shift_r_op, variable<PHOENIX_STD::PHOENIX_SSTREAM>, BaseT> + ::construct(var(_0), _1); +} + +////////////////////////////////// +template <typename T1> +struct binary_operator<shift_l_op, PHOENIX_STD::PHOENIX_SSTREAM, T1> +{ + typedef PHOENIX_STD::ostream& result_type; + static result_type eval(PHOENIX_STD::ostream& out, T1 const& rhs) + { return out << rhs; } +}; + +////////////////////////////////// +template <typename BaseT> +inline typename impl::make_binary3 + <shift_l_op, variable<PHOENIX_STD::PHOENIX_SSTREAM>, BaseT>::type +operator<<(PHOENIX_STD::PHOENIX_SSTREAM& _0, actor<BaseT> const& _1) +{ + return impl::make_binary3 + <shift_l_op, variable<PHOENIX_STD::PHOENIX_SSTREAM>, BaseT> + ::construct(var(_0), _1); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// I/O manipulator specializations +// +/////////////////////////////////////////////////////////////////////////////// +#if (!defined(__GNUC__) || (__GNUC__ > 2)) +// && !(defined(__ICL) && defined(_STLPORT_VERSION)) + +typedef PHOENIX_STD::ios_base& (*iomanip_t)(PHOENIX_STD::ios_base&); +typedef PHOENIX_STD::istream& (*imanip_t)(PHOENIX_STD::istream&); +typedef PHOENIX_STD::ostream& (*omanip_t)(PHOENIX_STD::ostream&); + +#if defined(__BORLANDC__) + +/////////////////////////////////////////////////////////////////////////////// +// +// Borland does not like i/o manipulators functions such as endl to +// be the rhs of a lazy << operator (Borland incorrectly reports +// ambiguity). To get around the problem, we provide function +// pointer versions of the same name with a single trailing +// underscore. +// +// You can use the same trick for other i/o manipulators. +// Alternatively, you can prefix the manipulator with a '&' +// operator. Example: +// +// cout << arg1 << &endl +// +/////////////////////////////////////////////////////////////////////////////// + +imanip_t ws_ = &PHOENIX_STD::ws; +iomanip_t dec_ = &PHOENIX_STD::dec; +iomanip_t hex_ = &PHOENIX_STD::hex; +iomanip_t oct_ = &PHOENIX_STD::oct; +omanip_t endl_ = &PHOENIX_STD::endl; +omanip_t ends_ = &PHOENIX_STD::ends; +omanip_t flush_ = &PHOENIX_STD::flush; + +#else // __BORLANDC__ + +/////////////////////////////////////////////////////////////////////////////// +// +// The following are overloads for I/O manipulators. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename BaseT> +inline typename impl::make_binary1<shift_l_op, BaseT, imanip_t>::type +operator>>(actor<BaseT> const& _0, imanip_t _1) +{ + return impl::make_binary1<shift_l_op, BaseT, imanip_t>::construct(_0, _1); +} + +////////////////////////////////// +template <typename BaseT> +inline typename impl::make_binary1<shift_l_op, BaseT, iomanip_t>::type +operator>>(actor<BaseT> const& _0, iomanip_t _1) +{ + return impl::make_binary1<shift_l_op, BaseT, iomanip_t>::construct(_0, _1); +} + +////////////////////////////////// +template <typename BaseT> +inline typename impl::make_binary1<shift_l_op, BaseT, omanip_t>::type +operator<<(actor<BaseT> const& _0, omanip_t _1) +{ + return impl::make_binary1<shift_l_op, BaseT, omanip_t>::construct(_0, _1); +} + +////////////////////////////////// +template <typename BaseT> +inline typename impl::make_binary1<shift_l_op, BaseT, iomanip_t>::type +operator<<(actor<BaseT> const& _0, iomanip_t _1) +{ + return impl::make_binary1<shift_l_op, BaseT, iomanip_t>::construct(_0, _1); +} + +#endif // __BORLANDC__ +#endif // !defined(__GNUC__) || (__GNUC__ > 2) + +/////////////////////////////////////////////////////////////////////////////// +// +// specializations for stl iterators and containers +// +/////////////////////////////////////////////////////////////////////////////// +template <typename T> +struct unary_operator<dereference_op, T> +{ + typedef typename T::reference result_type; + static result_type eval(T const& iter) + { return *iter; } +}; + +////////////////////////////////// +template <typename T0, typename T1> +struct binary_operator<index_op, T0, T1> +{ + typedef typename T0::reference result_type; + static result_type eval(T0& container, T1 const& index) + { return container[index]; } +}; + +////////////////////////////////// +template <typename T0, typename T1> +struct binary_operator<index_op, T0 const, T1> +{ + typedef typename T0::const_reference result_type; + static result_type eval(T0 const& container, T1 const& index) + { return container[index]; } +}; + +/////////////////////////////////////////////////////////////////////////////// +} // namespace phoenix + +#undef PHOENIX_SSTREAM +#undef PHOENIX_STD +#endif diff --git a/boost/spirit/home/classic/phoenix/statements.hpp b/boost/spirit/home/classic/phoenix/statements.hpp new file mode 100644 index 0000000000..25e6b1dd45 --- /dev/null +++ b/boost/spirit/home/classic/phoenix/statements.hpp @@ -0,0 +1,443 @@ +/*============================================================================= + Phoenix V1.2.1 + Copyright (c) 2001-2002 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) +==============================================================================*/ +#ifndef PHOENIX_STATEMENTS_HPP +#define PHOENIX_STATEMENTS_HPP + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/spirit/home/classic/phoenix/composite.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace phoenix { + +/////////////////////////////////////////////////////////////////////////////// +// +// sequential_composite +// +// Two or more actors separated by the comma generates a +// sequential_composite which is a composite actor. Example: +// +// actor, +// actor, +// actor +// +// The actors are evaluated sequentially. The result type of this +// is void. Note that the last actor should not have a trailing +// comma. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename A0, typename A1> +struct sequential_composite { + + typedef sequential_composite<A0, A1> self_t; + + template <typename TupleT> + struct result { typedef void type; }; + + sequential_composite(A0 const& _0, A1 const& _1) + : a0(_0), a1(_1) {} + + template <typename TupleT> + void + eval(TupleT const& args) const + { + a0.eval(args); + a1.eval(args); + } + + A0 a0; A1 a1; // actors +}; + +////////////////////////////////// +template <typename BaseT0, typename BaseT1> +inline actor<sequential_composite<actor<BaseT0>, actor<BaseT1> > > +operator,(actor<BaseT0> const& _0, actor<BaseT1> const& _1) +{ + return sequential_composite<actor<BaseT0>, actor<BaseT1> >(_0, _1); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// if_then_else_composite +// +// This composite has two (2) forms: +// +// if_(condition) +// [ +// statement +// ] +// +// and +// +// if_(condition) +// [ +// true_statement +// ] +// .else_ +// [ +// false_statement +// ] +// +// where condition is an actor that evaluates to bool. If condition +// is true, the true_statement (again an actor) is executed +// otherwise, the false_statement (another actor) is executed. The +// result type of this is void. Note the trailing underscore after +// if_ and the the leading dot and the trailing underscore before +// and after .else_. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename CondT, typename ThenT, typename ElseT> +struct if_then_else_composite { + + typedef if_then_else_composite<CondT, ThenT, ElseT> self_t; + + template <typename TupleT> + struct result { + + typedef void type; + }; + + if_then_else_composite( + CondT const& cond_, + ThenT const& then_, + ElseT const& else__) + : cond(cond_), then(then_), else_(else__) {} + + template <typename TupleT> + void eval(TupleT const& args) const + { + if (cond.eval(args)) + then.eval(args); + else + else_.eval(args); + } + + CondT cond; ThenT then; ElseT else_; // actors +}; + +////////////////////////////////// +template <typename CondT, typename ThenT> +struct else_gen { + + else_gen(CondT const& cond_, ThenT const& then_) + : cond(cond_), then(then_) {} + + template <typename ElseT> + actor<if_then_else_composite<CondT, ThenT, + typename as_actor<ElseT>::type> > + operator[](ElseT const& else_) + { + typedef if_then_else_composite<CondT, ThenT, + typename as_actor<ElseT>::type> + result; + + return result(cond, then, as_actor<ElseT>::convert(else_)); + } + + CondT cond; ThenT then; +}; + +////////////////////////////////// +template <typename CondT, typename ThenT> +struct if_then_composite { + + typedef if_then_composite<CondT, ThenT> self_t; + + template <typename TupleT> + struct result { typedef void type; }; + + if_then_composite(CondT const& cond_, ThenT const& then_) + : cond(cond_), then(then_), else_(cond, then) {} + + template <typename TupleT> + void eval(TupleT const& args) const + { + if (cond.eval(args)) + then.eval(args); + } + + CondT cond; ThenT then; // actors + else_gen<CondT, ThenT> else_; +}; + +////////////////////////////////// +template <typename CondT> +struct if_gen { + + if_gen(CondT const& cond_) + : cond(cond_) {} + + template <typename ThenT> + actor<if_then_composite< + typename as_actor<CondT>::type, + typename as_actor<ThenT>::type> > + operator[](ThenT const& then) const + { + typedef if_then_composite< + typename as_actor<CondT>::type, + typename as_actor<ThenT>::type> + result; + + return result( + as_actor<CondT>::convert(cond), + as_actor<ThenT>::convert(then)); + } + + CondT cond; +}; + +////////////////////////////////// +template <typename CondT> +inline if_gen<CondT> +if_(CondT const& cond) +{ + return if_gen<CondT>(cond); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// while_composite +// +// This composite has the form: +// +// while_(condition) +// [ +// statement +// ] +// +// While the condition (an actor) evaluates to true, statement +// (another actor) is executed. The result type of this is void. +// Note the trailing underscore after while_. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename CondT, typename DoT> +struct while_composite { + + typedef while_composite<CondT, DoT> self_t; + + template <typename TupleT> + struct result { typedef void type; }; + + while_composite(CondT const& cond_, DoT const& do__) + : cond(cond_), do_(do__) {} + + template <typename TupleT> + void eval(TupleT const& args) const + { + while (cond.eval(args)) + do_.eval(args); + } + + CondT cond; + DoT do_; +}; + +////////////////////////////////// +template <typename CondT> +struct while_gen { + + while_gen(CondT const& cond_) + : cond(cond_) {} + + template <typename DoT> + actor<while_composite< + typename as_actor<CondT>::type, + typename as_actor<DoT>::type> > + operator[](DoT const& do_) const + { + typedef while_composite< + typename as_actor<CondT>::type, + typename as_actor<DoT>::type> + result; + + return result( + as_actor<CondT>::convert(cond), + as_actor<DoT>::convert(do_)); + } + + CondT cond; +}; + +////////////////////////////////// +template <typename CondT> +inline while_gen<CondT> +while_(CondT const& cond) +{ + return while_gen<CondT>(cond); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// do_composite +// +// This composite has the form: +// +// do_ +// [ +// statement +// ] +// .while_(condition) +// +// While the condition (an actor) evaluates to true, statement +// (another actor) is executed. The statement is executed at least +// once. The result type of this is void. Note the trailing +// underscore after do_ and the the leading dot and the trailing +// underscore before and after .while_. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename DoT, typename CondT> +struct do_composite { + + typedef do_composite<DoT, CondT> self_t; + + template <typename TupleT> + struct result { typedef void type; }; + + do_composite(DoT const& do__, CondT const& cond_) + : do_(do__), cond(cond_) {} + + template <typename TupleT> + void eval(TupleT const& args) const + { + do + do_.eval(args); + while (cond.eval(args)); + } + + DoT do_; + CondT cond; +}; + +//////////////////////////////////// +template <typename DoT> +struct do_gen2 { + + do_gen2(DoT const& do__) + : do_(do__) {} + + template <typename CondT> + actor<do_composite< + typename as_actor<DoT>::type, + typename as_actor<CondT>::type> > + while_(CondT const& cond) const + { + typedef do_composite< + typename as_actor<DoT>::type, + typename as_actor<CondT>::type> + result; + + return result( + as_actor<DoT>::convert(do_), + as_actor<CondT>::convert(cond)); + } + + DoT do_; +}; + +//////////////////////////////////// +struct do_gen { + + template <typename DoT> + do_gen2<DoT> + operator[](DoT const& do_) const + { + return do_gen2<DoT>(do_); + } +}; + +do_gen const do_ = do_gen(); + +/////////////////////////////////////////////////////////////////////////////// +// +// for_composite +// +// This statement has the form: +// +// for_(init, condition, step) +// [ +// statement +// ] +// +// Where init, condition, step and statement are all actors. init +// is executed once before entering the for-loop. The for-loop +// exits once condition evaluates to false. At each loop iteration, +// step and statement is called. The result of this statement is +// void. Note the trailing underscore after for_. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename InitT, typename CondT, typename StepT, typename DoT> +struct for_composite { + + typedef composite<InitT, CondT, StepT, DoT> self_t; + + template <typename TupleT> + struct result { typedef void type; }; + + for_composite( + InitT const& init_, + CondT const& cond_, + StepT const& step_, + DoT const& do__) + : init(init_), cond(cond_), step(step_), do_(do__) {} + + template <typename TupleT> + void + eval(TupleT const& args) const + { + for (init.eval(args); cond.eval(args); step.eval(args)) + do_.eval(args); + } + + InitT init; CondT cond; StepT step; DoT do_; // actors +}; + +////////////////////////////////// +template <typename InitT, typename CondT, typename StepT> +struct for_gen { + + for_gen( + InitT const& init_, + CondT const& cond_, + StepT const& step_) + : init(init_), cond(cond_), step(step_) {} + + template <typename DoT> + actor<for_composite< + typename as_actor<InitT>::type, + typename as_actor<CondT>::type, + typename as_actor<StepT>::type, + typename as_actor<DoT>::type> > + operator[](DoT const& do_) const + { + typedef for_composite< + typename as_actor<InitT>::type, + typename as_actor<CondT>::type, + typename as_actor<StepT>::type, + typename as_actor<DoT>::type> + result; + + return result( + as_actor<InitT>::convert(init), + as_actor<CondT>::convert(cond), + as_actor<StepT>::convert(step), + as_actor<DoT>::convert(do_)); + } + + InitT init; CondT cond; StepT step; +}; + +////////////////////////////////// +template <typename InitT, typename CondT, typename StepT> +inline for_gen<InitT, CondT, StepT> +for_(InitT const& init, CondT const& cond, StepT const& step) +{ + return for_gen<InitT, CondT, StepT>(init, cond, step); +} + +} // namespace phoenix + +#endif diff --git a/boost/spirit/home/classic/phoenix/tuple_helpers.hpp b/boost/spirit/home/classic/phoenix/tuple_helpers.hpp new file mode 100644 index 0000000000..003d018f6c --- /dev/null +++ b/boost/spirit/home/classic/phoenix/tuple_helpers.hpp @@ -0,0 +1,1075 @@ +/*============================================================================= + Phoenix V1.2.1 + Copyright (c) 2002 Joel de Guzman + Copyright (c) 2002-2003 Hartmut Kaiser + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#ifndef PHOENIX_TUPLEHELPERS_HPP +#define PHOENIX_TUPLEHELPERS_HPP + +/////////////////////////////////////////////////////////////////////////////// +#include <cassert> +#include <boost/spirit/home/classic/phoenix/tuples.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace phoenix +{ + +/////////////////////////////////////////////////////////////////////////////// +// +// make_tuple template class +// +// This template class is used to calculate a tuple type required to hold +// the given template parameter type +// +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// normal (non-tuple types are wrapped into a tuple) +template <typename ResultT> +struct make_tuple { + + typedef tuple<ResultT> type; +}; + +/////////////////////////////////////////////////////////////////////////////// +// nil_t is converted to an empty tuple type +template <> +struct make_tuple<nil_t> { + + typedef tuple<> type; +}; + +/////////////////////////////////////////////////////////////////////////////// +// tuple types are left alone without any refactoring +template < + typename A, typename B, typename C +#if PHOENIX_LIMIT > 3 + , typename D, typename E, typename F +#if PHOENIX_LIMIT > 6 + , typename G, typename H, typename I +#if PHOENIX_LIMIT > 9 + , typename J, typename K, typename L +#if PHOENIX_LIMIT > 12 + , typename M, typename N, typename O +#endif +#endif +#endif +#endif +> +struct make_tuple<tuple<A, B, C +#if PHOENIX_LIMIT > 3 + , D, E, F +#if PHOENIX_LIMIT > 6 + , G, H, I +#if PHOENIX_LIMIT > 9 + , J, K, L +#if PHOENIX_LIMIT > 12 + , M, N, O +#endif +#endif +#endif +#endif + > > { + +// the tuple parameter itself is the required tuple type + typedef tuple<A, B, C +#if PHOENIX_LIMIT > 3 + , D, E, F +#if PHOENIX_LIMIT > 6 + , G, H, I +#if PHOENIX_LIMIT > 9 + , J, K, L +#if PHOENIX_LIMIT > 12 + , M, N, O +#endif +#endif +#endif +#endif + > type; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// concat_tuple type computer +// +// This class returns the type of a tuple, which is constructed by +// concatenating a tuple with a given type +// +/////////////////////////////////////////////////////////////////////////////// +template <typename TupleT, typename AppendT> +struct concat_tuple; + +/////////////////////////////////////////////////////////////////////////////// +// +// concat tuple <0 member> class +// +/////////////////////////////////////////////////////////////////////////////// +template <typename AppendT> +struct concat_tuple<tuple<>, AppendT> { + + typedef tuple<AppendT> type; +}; + +template <> +struct concat_tuple<tuple<>, nil_t> { + + typedef tuple<> type; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// concat tuple <1 member> class +// +/////////////////////////////////////////////////////////////////////////////// +template <typename A, typename AppendT> +struct concat_tuple<tuple<A>, AppendT> { + + typedef tuple<A, AppendT> type; +}; + +template <typename A> +struct concat_tuple<tuple<A>, nil_t> { + + typedef tuple<A> type; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// concat tuple <2 member> class +// +/////////////////////////////////////////////////////////////////////////////// +template <typename A, typename B, typename AppendT> +struct concat_tuple<tuple<A, B>, AppendT> { + + typedef tuple<A, B, AppendT> type; +}; + +template <typename A, typename B> +struct concat_tuple<tuple<A, B>, nil_t> { + + typedef tuple<A, B> type; +}; + +#if PHOENIX_LIMIT > 3 +/////////////////////////////////////////////////////////////////////////////// +// +// concat tuple <3 member> class +// +/////////////////////////////////////////////////////////////////////////////// +template < + typename A, typename B, typename C, + typename AppendT +> +struct concat_tuple<tuple<A, B, C>, AppendT> { + + typedef tuple<A, B, C, AppendT> type; +}; + +template < + typename A, typename B, typename C +> +struct concat_tuple<tuple<A, B, C>, nil_t> { + + typedef tuple<A, B, C> type; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// concat tuple <4 member> class +// +/////////////////////////////////////////////////////////////////////////////// +template < + typename A, typename B, typename C, typename D, + typename AppendT +> +struct concat_tuple<tuple<A, B, C, D>, AppendT> { + + typedef tuple<A, B, C, D, AppendT> type; +}; + +template < + typename A, typename B, typename C, typename D +> +struct concat_tuple<tuple<A, B, C, D>, nil_t> { + + typedef tuple<A, B, C, D> type; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// concat tuple <5 member> class +// +/////////////////////////////////////////////////////////////////////////////// +template < + typename A, typename B, typename C, typename D, typename E, + typename AppendT +> +struct concat_tuple<tuple<A, B, C, D, E>, AppendT> { + + typedef tuple<A, B, C, D, E, AppendT> type; +}; + +template < + typename A, typename B, typename C, typename D, typename E +> +struct concat_tuple<tuple<A, B, C, D, E>, nil_t> { + + typedef tuple<A, B, C, D, E> type; +}; + +#if PHOENIX_LIMIT > 6 +/////////////////////////////////////////////////////////////////////////////// +// +// concat tuple <6 member> class +// +/////////////////////////////////////////////////////////////////////////////// +template < + typename A, typename B, typename C, typename D, typename E, typename F, + typename AppendT +> +struct concat_tuple<tuple<A, B, C, D, E, F>, AppendT> { + + typedef tuple<A, B, C, D, E, F, AppendT> type; +}; + +template < + typename A, typename B, typename C, typename D, typename E, typename F +> +struct concat_tuple<tuple<A, B, C, D, E, F>, nil_t> { + + typedef tuple<A, B, C, D, E, F> type; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// concat tuple <7 member> class +// +/////////////////////////////////////////////////////////////////////////////// +template < + typename A, typename B, typename C, typename D, typename E, typename F, + typename G, + typename AppendT +> +struct concat_tuple<tuple<A, B, C, D, E, F, G>, AppendT> { + + typedef tuple<A, B, C, D, E, F, G, AppendT> type; +}; + +template < + typename A, typename B, typename C, typename D, typename E, typename F, + typename G +> +struct concat_tuple<tuple<A, B, C, D, E, F, G>, nil_t> { + + typedef tuple<A, B, C, D, E, F, G> type; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// concat tuple <8 member> class +// +/////////////////////////////////////////////////////////////////////////////// +template < + typename A, typename B, typename C, typename D, typename E, typename F, + typename G, typename H, + typename AppendT +> +struct concat_tuple<tuple<A, B, C, D, E, F, G, H>, AppendT> { + + typedef tuple<A, B, C, D, E, F, G, H, AppendT> type; +}; + +template < + typename A, typename B, typename C, typename D, typename E, typename F, + typename G, typename H +> +struct concat_tuple<tuple<A, B, C, D, E, F, G, H>, nil_t> { + + typedef tuple<A, B, C, D, E, F, G, H> type; +}; + +#if PHOENIX_LIMIT > 9 +/////////////////////////////////////////////////////////////////////////////// +// +// concat tuple <9 member> class +// +/////////////////////////////////////////////////////////////////////////////// +template < + typename A, typename B, typename C, typename D, typename E, typename F, + typename G, typename H, typename I, + typename AppendT +> +struct concat_tuple<tuple<A, B, C, D, E, F, G, H, I>, AppendT> { + + typedef tuple<A, B, C, D, E, F, G, H, I, AppendT> type; +}; + +template < + typename A, typename B, typename C, typename D, typename E, typename F, + typename G, typename H, typename I +> +struct concat_tuple<tuple<A, B, C, D, E, F, G, H, I>, nil_t> { + + typedef tuple<A, B, C, D, E, F, G, H, I> type; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// concat tuple <10 member> class +// +/////////////////////////////////////////////////////////////////////////////// +template < + typename A, typename B, typename C, typename D, typename E, typename F, + typename G, typename H, typename I, typename J, + typename AppendT +> +struct concat_tuple<tuple<A, B, C, D, E, F, G, H, I, J>, AppendT> { + + typedef tuple<A, B, C, D, E, F, G, H, I, J, AppendT> type; +}; + +template < + typename A, typename B, typename C, typename D, typename E, typename F, + typename G, typename H, typename I, typename J +> +struct concat_tuple<tuple<A, B, C, D, E, F, G, H, I, J>, nil_t> { + + typedef tuple<A, B, C, D, E, F, G, H, I, J> type; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// concat tuple <11 member> class +// +/////////////////////////////////////////////////////////////////////////////// +template < + typename A, typename B, typename C, typename D, typename E, typename F, + typename G, typename H, typename I, typename J, typename K, + typename AppendT +> +struct concat_tuple<tuple<A, B, C, D, E, F, G, H, I, J, K>, AppendT> { + + typedef tuple<A, B, C, D, E, F, G, H, I, J, K, AppendT> type; +}; + +template < + typename A, typename B, typename C, typename D, typename E, typename F, + typename G, typename H, typename I, typename J, typename K +> +struct concat_tuple<tuple<A, B, C, D, E, F, G, H, I, J, K>, nil_t> { + + typedef tuple<A, B, C, D, E, F, G, H, I, J, K> type; +}; + +#if PHOENIX_LIMIT > 12 +/////////////////////////////////////////////////////////////////////////////// +// +// concat tuple <12 member> class +// +/////////////////////////////////////////////////////////////////////////////// +template < + typename A, typename B, typename C, typename D, typename E, typename F, + typename G, typename H, typename I, typename J, typename K, typename L, + typename AppendT +> +struct concat_tuple<tuple<A, B, C, D, E, F, G, H, I, J, K, L>, AppendT> { + + typedef tuple<A, B, C, D, E, F, G, H, I, J, K, L, AppendT> type; +}; + +template < + typename A, typename B, typename C, typename D, typename E, typename F, + typename G, typename H, typename I, typename J, typename K, typename L +> +struct concat_tuple<tuple<A, B, C, D, E, F, G, H, I, J, K, L>, nil_t> { + + typedef tuple<A, B, C, D, E, F, G, H, I, J, K, L> type; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// concat tuple <13 member> class +// +/////////////////////////////////////////////////////////////////////////////// +template < + typename A, typename B, typename C, typename D, typename E, typename F, + typename G, typename H, typename I, typename J, typename K, typename L, + typename M, + typename AppendT +> +struct concat_tuple<tuple<A, B, C, D, E, F, G, H, I, J, K, L, M>, AppendT> { + + typedef tuple<A, B, C, D, E, F, G, H, I, J, K, L, M, AppendT> type; +}; + +template < + typename A, typename B, typename C, typename D, typename E, typename F, + typename G, typename H, typename I, typename J, typename K, typename L, + typename M +> +struct concat_tuple<tuple<A, B, C, D, E, F, G, H, I, J, K, L, M>, nil_t> { + + typedef tuple<A, B, C, D, E, F, G, H, I, J, K, L, M> type; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// concat tuple <14 member> class +// +/////////////////////////////////////////////////////////////////////////////// +template < + typename A, typename B, typename C, typename D, typename E, typename F, + typename G, typename H, typename I, typename J, typename K, typename L, + typename M, typename N, + typename AppendT +> +struct concat_tuple<tuple<A, B, C, D, E, F, G, H, I, J, K, L, M, N>, AppendT> { + + typedef tuple<A, B, C, D, E, F, G, H, I, J, K, L, M, N, AppendT> type; +}; + +template < + typename A, typename B, typename C, typename D, typename E, typename F, + typename G, typename H, typename I, typename J, typename K, typename L, + typename M, typename N +> +struct concat_tuple<tuple<A, B, C, D, E, F, G, H, I, J, K, L, M, N>, nil_t> { + + typedef tuple<A, B, C, D, E, F, G, H, I, J, K, L, M, N> type; +}; + +#endif +#endif +#endif +#endif + +/////////////////////////////////////////////////////////////////////////////// +// +// concat_tuples type computer +// +// This template class returns the type of a tuple built from the +// concatenation of two given tuples. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename TupleT1, typename TupleT2, int N, typename AppendT> +struct concat_tuple_element { + + typedef + typename concat_tuple_element< + typename concat_tuple<TupleT1, AppendT>::type, TupleT2, N+1, + typename tuple_element<N+1, TupleT2>::type + >::type + type; +}; + +template <typename TupleT1, typename TupleT2, int N> +struct concat_tuple_element<TupleT1, TupleT2, N, nil_t> { + + typedef TupleT1 type; +}; + +template <typename TupleT1, typename TupleT2> +struct concat_tuples { + + typedef + typename concat_tuple_element< + TupleT1, TupleT2, 0, + typename tuple_element<0, TupleT2>::type + >::type + type; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// convert_actors template function +// +// The convert_actors template functions constructs a new tuple object +// composed of the elements returned by the actors contained in the +// input tuple. (i.e. the given tuple type 'actor_tuple' contains a set +// of actors to evaluate and the resulting tuple contains the results of +// evaluating the actors.) +// +/////////////////////////////////////////////////////////////////////////////// +template <typename ActorT, typename TupleT> +struct actor_result; // forward declaration + +namespace impl +{ + template <unsigned N> + struct convert_actors_ {}; +} + +template <typename TupleResultT, typename ActorTupleT> +TupleResultT +convert_actors(ActorTupleT const& actor_tuple) +{ + BOOST_STATIC_ASSERT(ActorTupleT::length <= TupleResultT::length); + BOOST_STATIC_CONSTANT(int, length = TupleResultT::length); + return impl::convert_actors_<length> + ::template apply<TupleResultT, ActorTupleT>::do_(actor_tuple); +} + +namespace impl +{ + template <int N, typename TupleResultT, typename ActorTupleT> + struct convert_actor + { + typedef typename tuple_element<N, TupleResultT>::type type; + + template <bool C> + struct is_default_t {}; + typedef is_default_t<true> is_default; + typedef is_default_t<false> is_not_default; + + static type + actor_element(ActorTupleT const& /*actor_tuple*/, is_default) + { + return type(); // default construct + } + + static type + actor_element(ActorTupleT const& actor_tuple, is_not_default) + { + BOOST_STATIC_ASSERT(ActorTupleT::length <= TupleResultT::length); + return actor_tuple[tuple_index<N>()](); // apply the actor + } + + static type + do_(ActorTupleT const& actor_tuple) + { + return actor_element( + actor_tuple, is_default_t<(N >= ActorTupleT::length)>()); + } + }; + + /////////////////////////////////////// + template <> + struct convert_actors_<1> + { + template <typename TupleResultT, typename ActorTupleT> + struct apply + { + static TupleResultT + do_(ActorTupleT const& actor_tuple) + { + typedef impl::convert_actor<0, TupleResultT, ActorTupleT> converter0; + + return TupleResultT( + converter0::do_(actor_tuple) + ); + } + }; + }; + + /////////////////////////////////////// + template <> + struct convert_actors_<2> + { + template <typename TupleResultT, typename ActorTupleT> + struct apply + { + static TupleResultT + do_(ActorTupleT const& actor_tuple) + { + typedef impl::convert_actor<0, TupleResultT, ActorTupleT> converter0; + typedef impl::convert_actor<1, TupleResultT, ActorTupleT> converter1; + + using namespace tuple_index_names; + return TupleResultT( + converter0::do_(actor_tuple) + , converter1::do_(actor_tuple) + ); + } + }; + }; + + /////////////////////////////////////// + template <> + struct convert_actors_<3> + { + template <typename TupleResultT, typename ActorTupleT> + struct apply + { + static TupleResultT + do_(ActorTupleT const& actor_tuple) + { + typedef impl::convert_actor<0, TupleResultT, ActorTupleT> converter0; + typedef impl::convert_actor<1, TupleResultT, ActorTupleT> converter1; + typedef impl::convert_actor<2, TupleResultT, ActorTupleT> converter2; + + using namespace tuple_index_names; + return TupleResultT( + converter0::do_(actor_tuple) + , converter1::do_(actor_tuple) + , converter2::do_(actor_tuple) + ); + } + }; + }; + + #if PHOENIX_LIMIT > 3 + + ///////////////////////////////////// + template <> + struct convert_actors_<4> + { + template <typename TupleResultT, typename ActorTupleT> + struct apply + { + static TupleResultT + do_(ActorTupleT const& actor_tuple) + { + typedef impl::convert_actor<0, TupleResultT, ActorTupleT> converter0; + typedef impl::convert_actor<1, TupleResultT, ActorTupleT> converter1; + typedef impl::convert_actor<2, TupleResultT, ActorTupleT> converter2; + typedef impl::convert_actor<3, TupleResultT, ActorTupleT> converter3; + + using namespace tuple_index_names; + return TupleResultT( + converter0::do_(actor_tuple) + , converter1::do_(actor_tuple) + , converter2::do_(actor_tuple) + , converter3::do_(actor_tuple) + ); + } + }; + }; + + ///////////////////////////////////// + template <> + struct convert_actors_<5> + { + template <typename TupleResultT, typename ActorTupleT> + struct apply + { + static TupleResultT + do_(ActorTupleT const& actor_tuple) + { + typedef impl::convert_actor<0, TupleResultT, ActorTupleT> converter0; + typedef impl::convert_actor<1, TupleResultT, ActorTupleT> converter1; + typedef impl::convert_actor<2, TupleResultT, ActorTupleT> converter2; + typedef impl::convert_actor<3, TupleResultT, ActorTupleT> converter3; + typedef impl::convert_actor<4, TupleResultT, ActorTupleT> converter4; + + using namespace tuple_index_names; + return TupleResultT( + converter0::do_(actor_tuple) + , converter1::do_(actor_tuple) + , converter2::do_(actor_tuple) + , converter3::do_(actor_tuple) + , converter4::do_(actor_tuple) + ); + } + }; + }; + + ///////////////////////////////////// + template <> + struct convert_actors_<6> + { + template <typename TupleResultT, typename ActorTupleT> + struct apply + { + static TupleResultT + do_(ActorTupleT const& actor_tuple) + { + typedef impl::convert_actor<0, TupleResultT, ActorTupleT> converter0; + typedef impl::convert_actor<1, TupleResultT, ActorTupleT> converter1; + typedef impl::convert_actor<2, TupleResultT, ActorTupleT> converter2; + typedef impl::convert_actor<3, TupleResultT, ActorTupleT> converter3; + typedef impl::convert_actor<4, TupleResultT, ActorTupleT> converter4; + typedef impl::convert_actor<5, TupleResultT, ActorTupleT> converter5; + + using namespace tuple_index_names; + return TupleResultT( + converter0::do_(actor_tuple) + , converter1::do_(actor_tuple) + , converter2::do_(actor_tuple) + , converter3::do_(actor_tuple) + , converter4::do_(actor_tuple) + , converter5::do_(actor_tuple) + ); + } + }; + }; + + #if PHOENIX_LIMIT > 6 + + ///////////////////////////////////// + template <> + struct convert_actors_<7> + { + template <typename TupleResultT, typename ActorTupleT> + struct apply + { + static TupleResultT + do_(ActorTupleT const& actor_tuple) + { + typedef impl::convert_actor<0, TupleResultT, ActorTupleT> converter0; + typedef impl::convert_actor<1, TupleResultT, ActorTupleT> converter1; + typedef impl::convert_actor<2, TupleResultT, ActorTupleT> converter2; + typedef impl::convert_actor<3, TupleResultT, ActorTupleT> converter3; + typedef impl::convert_actor<4, TupleResultT, ActorTupleT> converter4; + typedef impl::convert_actor<5, TupleResultT, ActorTupleT> converter5; + typedef impl::convert_actor<6, TupleResultT, ActorTupleT> converter6; + + using namespace tuple_index_names; + return TupleResultT( + converter0::do_(actor_tuple) + , converter1::do_(actor_tuple) + , converter2::do_(actor_tuple) + , converter3::do_(actor_tuple) + , converter4::do_(actor_tuple) + , converter5::do_(actor_tuple) + , converter6::do_(actor_tuple) + ); + } + }; + }; + + ///////////////////////////////////// + template <> + struct convert_actors_<8> + { + template <typename TupleResultT, typename ActorTupleT> + struct apply + { + static TupleResultT + do_(ActorTupleT const& actor_tuple) + { + typedef impl::convert_actor<0, TupleResultT, ActorTupleT> converter0; + typedef impl::convert_actor<1, TupleResultT, ActorTupleT> converter1; + typedef impl::convert_actor<2, TupleResultT, ActorTupleT> converter2; + typedef impl::convert_actor<3, TupleResultT, ActorTupleT> converter3; + typedef impl::convert_actor<4, TupleResultT, ActorTupleT> converter4; + typedef impl::convert_actor<5, TupleResultT, ActorTupleT> converter5; + typedef impl::convert_actor<6, TupleResultT, ActorTupleT> converter6; + typedef impl::convert_actor<7, TupleResultT, ActorTupleT> converter7; + + using namespace tuple_index_names; + return TupleResultT( + converter0::do_(actor_tuple) + , converter1::do_(actor_tuple) + , converter2::do_(actor_tuple) + , converter3::do_(actor_tuple) + , converter4::do_(actor_tuple) + , converter5::do_(actor_tuple) + , converter6::do_(actor_tuple) + , converter7::do_(actor_tuple) + ); + } + }; + }; + + ///////////////////////////////////// + template <> + struct convert_actors_<9> + { + template <typename TupleResultT, typename ActorTupleT> + struct apply + { + static TupleResultT + do_(ActorTupleT const& actor_tuple) + { + typedef impl::convert_actor<0, TupleResultT, ActorTupleT> converter0; + typedef impl::convert_actor<1, TupleResultT, ActorTupleT> converter1; + typedef impl::convert_actor<2, TupleResultT, ActorTupleT> converter2; + typedef impl::convert_actor<3, TupleResultT, ActorTupleT> converter3; + typedef impl::convert_actor<4, TupleResultT, ActorTupleT> converter4; + typedef impl::convert_actor<5, TupleResultT, ActorTupleT> converter5; + typedef impl::convert_actor<6, TupleResultT, ActorTupleT> converter6; + typedef impl::convert_actor<7, TupleResultT, ActorTupleT> converter7; + typedef impl::convert_actor<8, TupleResultT, ActorTupleT> converter8; + + using namespace tuple_index_names; + return TupleResultT( + converter0::do_(actor_tuple) + , converter1::do_(actor_tuple) + , converter2::do_(actor_tuple) + , converter3::do_(actor_tuple) + , converter4::do_(actor_tuple) + , converter5::do_(actor_tuple) + , converter6::do_(actor_tuple) + , converter7::do_(actor_tuple) + , converter8::do_(actor_tuple) + ); + } + }; + }; + + #if PHOENIX_LIMIT > 9 + + ///////////////////////////////////// + template <> + struct convert_actors_<10> + { + template <typename TupleResultT, typename ActorTupleT> + struct apply + { + static TupleResultT + do_(ActorTupleT const& actor_tuple) + { + typedef impl::convert_actor<0, TupleResultT, ActorTupleT> converter0; + typedef impl::convert_actor<1, TupleResultT, ActorTupleT> converter1; + typedef impl::convert_actor<2, TupleResultT, ActorTupleT> converter2; + typedef impl::convert_actor<3, TupleResultT, ActorTupleT> converter3; + typedef impl::convert_actor<4, TupleResultT, ActorTupleT> converter4; + typedef impl::convert_actor<5, TupleResultT, ActorTupleT> converter5; + typedef impl::convert_actor<6, TupleResultT, ActorTupleT> converter6; + typedef impl::convert_actor<7, TupleResultT, ActorTupleT> converter7; + typedef impl::convert_actor<8, TupleResultT, ActorTupleT> converter8; + typedef impl::convert_actor<9, TupleResultT, ActorTupleT> converter9; + + using namespace tuple_index_names; + return TupleResultT( + converter0::do_(actor_tuple) + , converter1::do_(actor_tuple) + , converter2::do_(actor_tuple) + , converter3::do_(actor_tuple) + , converter4::do_(actor_tuple) + , converter5::do_(actor_tuple) + , converter6::do_(actor_tuple) + , converter7::do_(actor_tuple) + , converter8::do_(actor_tuple) + , converter9::do_(actor_tuple) + ); + } + }; + }; + + ///////////////////////////////////// + template <> + struct convert_actors_<11> + { + template <typename TupleResultT, typename ActorTupleT> + struct apply + { + static TupleResultT + do_(ActorTupleT const& actor_tuple) + { + typedef impl::convert_actor<0, TupleResultT, ActorTupleT> converter0; + typedef impl::convert_actor<1, TupleResultT, ActorTupleT> converter1; + typedef impl::convert_actor<2, TupleResultT, ActorTupleT> converter2; + typedef impl::convert_actor<3, TupleResultT, ActorTupleT> converter3; + typedef impl::convert_actor<4, TupleResultT, ActorTupleT> converter4; + typedef impl::convert_actor<5, TupleResultT, ActorTupleT> converter5; + typedef impl::convert_actor<6, TupleResultT, ActorTupleT> converter6; + typedef impl::convert_actor<7, TupleResultT, ActorTupleT> converter7; + typedef impl::convert_actor<8, TupleResultT, ActorTupleT> converter8; + typedef impl::convert_actor<9, TupleResultT, ActorTupleT> converter9; + typedef impl::convert_actor<10, TupleResultT, ActorTupleT> converter10; + + using namespace tuple_index_names; + return TupleResultT( + converter0::do_(actor_tuple) + , converter1::do_(actor_tuple) + , converter2::do_(actor_tuple) + , converter3::do_(actor_tuple) + , converter4::do_(actor_tuple) + , converter5::do_(actor_tuple) + , converter6::do_(actor_tuple) + , converter7::do_(actor_tuple) + , converter8::do_(actor_tuple) + , converter9::do_(actor_tuple) + , converter10::do_(actor_tuple) + ); + } + }; + }; + + ///////////////////////////////////// + template <> + struct convert_actors_<12> + { + template <typename TupleResultT, typename ActorTupleT> + struct apply + { + static TupleResultT + do_(ActorTupleT const& actor_tuple) + { + typedef impl::convert_actor<0, TupleResultT, ActorTupleT> converter0; + typedef impl::convert_actor<1, TupleResultT, ActorTupleT> converter1; + typedef impl::convert_actor<2, TupleResultT, ActorTupleT> converter2; + typedef impl::convert_actor<3, TupleResultT, ActorTupleT> converter3; + typedef impl::convert_actor<4, TupleResultT, ActorTupleT> converter4; + typedef impl::convert_actor<5, TupleResultT, ActorTupleT> converter5; + typedef impl::convert_actor<6, TupleResultT, ActorTupleT> converter6; + typedef impl::convert_actor<7, TupleResultT, ActorTupleT> converter7; + typedef impl::convert_actor<8, TupleResultT, ActorTupleT> converter8; + typedef impl::convert_actor<9, TupleResultT, ActorTupleT> converter9; + typedef impl::convert_actor<10, TupleResultT, ActorTupleT> converter10; + typedef impl::convert_actor<11, TupleResultT, ActorTupleT> converter11; + + using namespace tuple_index_names; + return TupleResultT( + converter0::do_(actor_tuple) + , converter1::do_(actor_tuple) + , converter2::do_(actor_tuple) + , converter3::do_(actor_tuple) + , converter4::do_(actor_tuple) + , converter5::do_(actor_tuple) + , converter6::do_(actor_tuple) + , converter7::do_(actor_tuple) + , converter8::do_(actor_tuple) + , converter9::do_(actor_tuple) + , converter10::do_(actor_tuple) + , converter11::do_(actor_tuple) + ); + } + }; + }; + + #if PHOENIX_LIMIT > 12 + + ///////////////////////////////////// + template <> + struct convert_actors_<13> + { + template <typename TupleResultT, typename ActorTupleT> + struct apply + { + static TupleResultT + do_(ActorTupleT const& actor_tuple) + { + typedef impl::convert_actor<0, TupleResultT, ActorTupleT> converter0; + typedef impl::convert_actor<1, TupleResultT, ActorTupleT> converter1; + typedef impl::convert_actor<2, TupleResultT, ActorTupleT> converter2; + typedef impl::convert_actor<3, TupleResultT, ActorTupleT> converter3; + typedef impl::convert_actor<4, TupleResultT, ActorTupleT> converter4; + typedef impl::convert_actor<5, TupleResultT, ActorTupleT> converter5; + typedef impl::convert_actor<6, TupleResultT, ActorTupleT> converter6; + typedef impl::convert_actor<7, TupleResultT, ActorTupleT> converter7; + typedef impl::convert_actor<8, TupleResultT, ActorTupleT> converter8; + typedef impl::convert_actor<9, TupleResultT, ActorTupleT> converter9; + typedef impl::convert_actor<10, TupleResultT, ActorTupleT> converter10; + typedef impl::convert_actor<11, TupleResultT, ActorTupleT> converter11; + typedef impl::convert_actor<12, TupleResultT, ActorTupleT> converter12; + + using namespace tuple_index_names; + return TupleResultT( + converter0::do_(actor_tuple) + , converter1::do_(actor_tuple) + , converter2::do_(actor_tuple) + , converter3::do_(actor_tuple) + , converter4::do_(actor_tuple) + , converter5::do_(actor_tuple) + , converter6::do_(actor_tuple) + , converter7::do_(actor_tuple) + , converter8::do_(actor_tuple) + , converter9::do_(actor_tuple) + , converter10::do_(actor_tuple) + , converter11::do_(actor_tuple) + , converter12::do_(actor_tuple) + ); + } + }; + }; + + /////////////////////////////////////// + template <> + struct convert_actors_<14> + { + template <typename TupleResultT, typename ActorTupleT> + struct apply + { + static TupleResultT + do_(ActorTupleT const& actor_tuple) + { + typedef impl::convert_actor<0, TupleResultT, ActorTupleT> converter0; + typedef impl::convert_actor<1, TupleResultT, ActorTupleT> converter1; + typedef impl::convert_actor<2, TupleResultT, ActorTupleT> converter2; + typedef impl::convert_actor<3, TupleResultT, ActorTupleT> converter3; + typedef impl::convert_actor<4, TupleResultT, ActorTupleT> converter4; + typedef impl::convert_actor<5, TupleResultT, ActorTupleT> converter5; + typedef impl::convert_actor<6, TupleResultT, ActorTupleT> converter6; + typedef impl::convert_actor<7, TupleResultT, ActorTupleT> converter7; + typedef impl::convert_actor<8, TupleResultT, ActorTupleT> converter8; + typedef impl::convert_actor<9, TupleResultT, ActorTupleT> converter9; + typedef impl::convert_actor<10, TupleResultT, ActorTupleT> converter10; + typedef impl::convert_actor<11, TupleResultT, ActorTupleT> converter11; + typedef impl::convert_actor<12, TupleResultT, ActorTupleT> converter12; + typedef impl::convert_actor<13, TupleResultT, ActorTupleT> converter13; + + using namespace tuple_index_names; + return TupleResultT( + converter0::do_(actor_tuple) + , converter1::do_(actor_tuple) + , converter2::do_(actor_tuple) + , converter3::do_(actor_tuple) + , converter4::do_(actor_tuple) + , converter5::do_(actor_tuple) + , converter6::do_(actor_tuple) + , converter7::do_(actor_tuple) + , converter8::do_(actor_tuple) + , converter9::do_(actor_tuple) + , converter10::do_(actor_tuple) + , converter11::do_(actor_tuple) + , converter12::do_(actor_tuple) + , converter13::do_(actor_tuple) + ); + } + }; + }; + + /////////////////////////////////////// + template <> + struct convert_actors_<15> + { + template <typename TupleResultT, typename ActorTupleT> + struct apply + { + static TupleResultT + do_(ActorTupleT const& actor_tuple) + { + typedef impl::convert_actor<0, TupleResultT, ActorTupleT> converter0; + typedef impl::convert_actor<1, TupleResultT, ActorTupleT> converter1; + typedef impl::convert_actor<2, TupleResultT, ActorTupleT> converter2; + typedef impl::convert_actor<3, TupleResultT, ActorTupleT> converter3; + typedef impl::convert_actor<4, TupleResultT, ActorTupleT> converter4; + typedef impl::convert_actor<5, TupleResultT, ActorTupleT> converter5; + typedef impl::convert_actor<6, TupleResultT, ActorTupleT> converter6; + typedef impl::convert_actor<7, TupleResultT, ActorTupleT> converter7; + typedef impl::convert_actor<8, TupleResultT, ActorTupleT> converter8; + typedef impl::convert_actor<9, TupleResultT, ActorTupleT> converter9; + typedef impl::convert_actor<10, TupleResultT, ActorTupleT> converter10; + typedef impl::convert_actor<11, TupleResultT, ActorTupleT> converter11; + typedef impl::convert_actor<12, TupleResultT, ActorTupleT> converter12; + typedef impl::convert_actor<13, TupleResultT, ActorTupleT> converter13; + typedef impl::convert_actor<14, TupleResultT, ActorTupleT> converter14; + + using namespace tuple_index_names; + return TupleResultT( + converter0::do_(actor_tuple) + , converter1::do_(actor_tuple) + , converter2::do_(actor_tuple) + , converter3::do_(actor_tuple) + , converter4::do_(actor_tuple) + , converter5::do_(actor_tuple) + , converter6::do_(actor_tuple) + , converter7::do_(actor_tuple) + , converter8::do_(actor_tuple) + , converter9::do_(actor_tuple) + , converter10::do_(actor_tuple) + , converter11::do_(actor_tuple) + , converter12::do_(actor_tuple) + , converter13::do_(actor_tuple) + , converter14::do_(actor_tuple) + ); + } + }; + }; + + #endif + #endif + #endif + #endif +} // namespace impl + + +/////////////////////////////////////////////////////////////////////////////// +} // namespace phoenix + +#endif // PHOENIX_TUPLEHELPERS_HPP diff --git a/boost/spirit/home/classic/phoenix/tuples.hpp b/boost/spirit/home/classic/phoenix/tuples.hpp new file mode 100644 index 0000000000..50cec6bf3f --- /dev/null +++ b/boost/spirit/home/classic/phoenix/tuples.hpp @@ -0,0 +1,1338 @@ +/*============================================================================= + Phoenix V1.2.1 + Copyright (c) 2001-2002 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) +==============================================================================*/ +#ifndef PHOENIX_TUPLES_HPP +#define PHOENIX_TUPLES_HPP + +#if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300) +#error "Sorry, Phoenix does not support VC6 and VC7. Please upgrade to at least VC7.1" +#endif + +/////////////////////////////////////////////////////////////////////////////// +// +// Phoenix predefined maximum limit. This limit defines the maximum +// number of elements a tuple can hold. This number defaults to 3. The +// actual maximum is rounded up in multiples of 3. Thus, if this value +// is 4, the actual limit is 6. The ultimate maximum limit in this +// implementation is 15. +// +/////////////////////////////////////////////////////////////////////////////// +#ifndef PHOENIX_LIMIT +#define PHOENIX_LIMIT 3 +#endif + +#if defined(__BORLANDC__) && (__BORLANDC__ <= 0x561) +namespace phoenix { namespace borland_only +{ + namespace ftors + { + // We define these dummy template functions. Borland complains when + // a template class has the same name as a template function, + // regardless if they are in different namespaces. + + template <typename T> void if_(T) {} + template <typename T> void for_(T) {} + template <typename T> void while_(T) {} + template <typename T> void do_(T) {} + } + + namespace tmpls + { + // We define these dummy template functions. Borland complains when + // a template class has the same name as a template function, + // regardless if they are in different namespaces. + + template <typename T> struct if_ {}; + template <typename T> struct for_ {}; + template <typename T> struct while_ {}; + template <typename T> struct do_ {}; + } + +}} // namespace phoenix::borland_only +#endif + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/static_assert.hpp> +#include <boost/call_traits.hpp> +#include <boost/type_traits/remove_reference.hpp> + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(push) +#pragma warning(disable:4512) //assignment operator could not be generated +#endif + +/////////////////////////////////////////////////////////////////////////////// +namespace phoenix { + +/////////////////////////////////////////////////////////////////////////////// +// +// tuple +// +// Tuples hold heterogeneous types up to a predefined maximum. Only +// the most basic functionality needed is provided. Unlike other +// recursive list-like tuple implementations, this tuple +// implementation uses simple structs similar to std::pair with +// specialization for 0 to N tuple elements. +// +// 1) Construction +// Here are examples on how to construct tuples: +// +// typedef tuple<int, char> t1_t; +// typedef tuple<int, std::string, double> t2_t; +// +// // this tuple has an int and char members +// t1_t t1(3, 'c'); +// +// // this tuple has an int, std::string and double members +// t2_t t2(3, "hello", 3.14); +// +// Tuples can also be constructed from other tuples. The +// source and destination tuples need not have exactly the +// same element types. The only requirement is that the +// source tuple have the same number of elements as the +// destination and that each element slot in the +// destination can be copy constructed from the source +// element. For example: +// +// tuple<double, double> t3(t1); // OK. Compatible tuples +// tuple<double, double> t4(t2); // Error! Incompatible tuples +// +// 2) Member access +// A member in a tuple can be accessed using the +// tuple's [] operator by specifying the Nth +// tuple_index. Here are some examples: +// +// tuple_index<0> ix0; // 0th index == 1st item +// tuple_index<1> ix1; // 1st index == 2nd item +// tuple_index<2> ix2; // 2nd index == 3rd item +// +// t1[ix0] = 33; // sets the int member of the tuple t1 +// t2[ix2] = 6e6; // sets the double member of the tuple t2 +// t1[ix1] = 'a'; // sets the char member of the tuple t1 +// +// There are some predefined names are provided in sub- +// namespace tuple_index_names: +// +// tuple_index<0> _1; +// tuple_index<1> _2; +// ... +// tuple_index<N> _N; +// +// These indexes may be used by 'using' namespace +// phoenix::tuple_index_names. +// +// Access to out of bound indexes returns a nil_t value. +// +// 3) Member type inquiry +// The type of an individual member can be queried. +// Example: +// +// tuple_element<1, t2_t>::type +// +// Refers to the type of the second member (note zero based, +// thus 0 = 1st item, 1 = 2nd item) of the tuple. +// +// Aside from tuple_element<N, T>::type, there are two +// more types that tuple_element provides: rtype and +// crtype. While 'type' is the plain underlying type, +// 'rtype' is the reference type, or type& and 'crtype' +// is the constant reference type or type const&. The +// latter two are provided to make it easy for the +// client in dealing with the possibility of reference +// to reference when type is already a reference, which +// is illegal in C++. +// +// Access to out of bound indexes returns a nil_t type. +// +// 4) Tuple length +// The number of elements in a tuple can be queried. +// Example: +// +// int n = t1.length; +// +// gets the number of elements in tuple t1. +// +// length is a static constant. Thus, TupleT::length +// also works. Example: +// +// int n = t1_t::length; +// +/////////////////////////////////////////////////////////////////////////////// +struct nil_t {}; +using boost::remove_reference; +using boost::call_traits; + +////////////////////////////////// +namespace impl { + + template <typename T> + struct access { + + typedef const T& ctype; + typedef T& type; + }; + + template <typename T> + struct access<T&> { + + typedef T& ctype; + typedef T& type; + }; +} + +/////////////////////////////////////////////////////////////////////////////// +// +// tuple_element +// +// A query class that gets the Nth element inside a tuple. +// Examples: +// +// tuple_element<1, tuple<int, char, void*> >::type // plain +// tuple_element<1, tuple<int, char, void*> >::rtype // ref +// tuple_element<1, tuple<int, char, void*> >::crtype // const ref +// +// Has type char which is the 2nd type in the tuple +// (note zero based, thus 0 = 1st item, 1 = 2nd item). +// +// Given a tuple object, the static function tuple_element<N, +// TupleT>::get(tuple) gets the Nth element in the tuple. The +// tuple class' tuple::operator[] uses this to get its Nth +// element. +// +/////////////////////////////////////////////////////////////////////////////// +template <int N, typename TupleT> +struct tuple_element +{ + typedef nil_t type; + typedef nil_t& rtype; + typedef nil_t const& crtype; + + static nil_t get(TupleT const& t) { return nil_t(); } +}; + +////////////////////////////////// +template <typename TupleT> +struct tuple_element<0, TupleT> +{ + typedef typename TupleT::a_type type; + typedef typename impl::access<type>::type rtype; + typedef typename impl::access<type>::ctype crtype; + + static rtype get(TupleT& t) { return t.a; } + static crtype get(TupleT const& t) { return t.a; } +}; + +////////////////////////////////// +template <typename TupleT> +struct tuple_element<1, TupleT> +{ + typedef typename TupleT::b_type type; + typedef typename impl::access<type>::type rtype; + typedef typename impl::access<type>::ctype crtype; + + static rtype get(TupleT& t) { return t.b; } + static crtype get(TupleT const& t) { return t.b; } +}; + +////////////////////////////////// +template <typename TupleT> +struct tuple_element<2, TupleT> +{ + typedef typename TupleT::c_type type; + typedef typename impl::access<type>::type rtype; + typedef typename impl::access<type>::ctype crtype; + + static rtype get(TupleT& t) { return t.c; } + static crtype get(TupleT const& t) { return t.c; } +}; + +#if PHOENIX_LIMIT > 3 +////////////////////////////////// +template <typename TupleT> +struct tuple_element<3, TupleT> +{ + typedef typename TupleT::d_type type; + typedef typename impl::access<type>::type rtype; + typedef typename impl::access<type>::ctype crtype; + + static rtype get(TupleT& t) { return t.d; } + static crtype get(TupleT const& t) { return t.d; } +}; + +////////////////////////////////// +template <typename TupleT> +struct tuple_element<4, TupleT> +{ + typedef typename TupleT::e_type type; + typedef typename impl::access<type>::type rtype; + typedef typename impl::access<type>::ctype crtype; + + static rtype get(TupleT& t) { return t.e; } + static crtype get(TupleT const& t) { return t.e; } +}; + +////////////////////////////////// +template <typename TupleT> +struct tuple_element<5, TupleT> +{ + typedef typename TupleT::f_type type; + typedef typename impl::access<type>::type rtype; + typedef typename impl::access<type>::ctype crtype; + + static rtype get(TupleT& t) { return t.f; } + static crtype get(TupleT const& t) { return t.f; } +}; + +#if PHOENIX_LIMIT > 6 +////////////////////////////////// +template <typename TupleT> +struct tuple_element<6, TupleT> +{ + typedef typename TupleT::g_type type; + typedef typename impl::access<type>::type rtype; + typedef typename impl::access<type>::ctype crtype; + + static rtype get(TupleT& t) { return t.g; } + static crtype get(TupleT const& t) { return t.g; } +}; + +////////////////////////////////// +template <typename TupleT> +struct tuple_element<7, TupleT> +{ + typedef typename TupleT::h_type type; + typedef typename impl::access<type>::type rtype; + typedef typename impl::access<type>::ctype crtype; + + static rtype get(TupleT& t) { return t.h; } + static crtype get(TupleT const& t) { return t.h; } +}; + +////////////////////////////////// +template <typename TupleT> +struct tuple_element<8, TupleT> +{ + typedef typename TupleT::i_type type; + typedef typename impl::access<type>::type rtype; + typedef typename impl::access<type>::ctype crtype; + + static rtype get(TupleT& t) { return t.i; } + static crtype get(TupleT const& t) { return t.i; } +}; + +#if PHOENIX_LIMIT > 9 +////////////////////////////////// +template <typename TupleT> +struct tuple_element<9, TupleT> +{ + typedef typename TupleT::j_type type; + typedef typename impl::access<type>::type rtype; + typedef typename impl::access<type>::ctype crtype; + + static rtype get(TupleT& t) { return t.j; } + static crtype get(TupleT const& t) { return t.j; } +}; + +////////////////////////////////// +template <typename TupleT> +struct tuple_element<10, TupleT> +{ + typedef typename TupleT::k_type type; + typedef typename impl::access<type>::type rtype; + typedef typename impl::access<type>::ctype crtype; + + static rtype get(TupleT& t) { return t.k; } + static crtype get(TupleT const& t) { return t.k; } +}; + +////////////////////////////////// +template <typename TupleT> +struct tuple_element<11, TupleT> +{ + typedef typename TupleT::l_type type; + typedef typename impl::access<type>::type rtype; + typedef typename impl::access<type>::ctype crtype; + + static rtype get(TupleT& t) { return t.l; } + static crtype get(TupleT const& t) { return t.l; } +}; + +#if PHOENIX_LIMIT > 12 +////////////////////////////////// +template <typename TupleT> +struct tuple_element<12, TupleT> +{ + typedef typename TupleT::m_type type; + typedef typename impl::access<type>::type rtype; + typedef typename impl::access<type>::ctype crtype; + + static rtype get(TupleT& t) { return t.m; } + static crtype get(TupleT const& t) { return t.m; } +}; + +////////////////////////////////// +template <typename TupleT> +struct tuple_element<13, TupleT> +{ + typedef typename TupleT::n_type type; + typedef typename impl::access<type>::type rtype; + typedef typename impl::access<type>::ctype crtype; + + static rtype get(TupleT& t) { return t.n; } + static crtype get(TupleT const& t) { return t.n; } +}; + +////////////////////////////////// +template <typename TupleT> +struct tuple_element<14, TupleT> +{ + typedef typename TupleT::o_type type; + typedef typename impl::access<type>::type rtype; + typedef typename impl::access<type>::ctype crtype; + + static rtype get(TupleT& t) { return t.o; } + static crtype get(TupleT const& t) { return t.o; } +}; + +#endif +#endif +#endif +#endif + +/////////////////////////////////////////////////////////////////////////////// +// +// tuple forward declaration. +// +/////////////////////////////////////////////////////////////////////////////// +template < + typename A = nil_t + , typename B = nil_t + , typename C = nil_t + +#if PHOENIX_LIMIT > 3 + , typename D = nil_t + , typename E = nil_t + , typename F = nil_t + +#if PHOENIX_LIMIT > 6 + , typename G = nil_t + , typename H = nil_t + , typename I = nil_t + +#if PHOENIX_LIMIT > 9 + , typename J = nil_t + , typename K = nil_t + , typename L = nil_t + +#if PHOENIX_LIMIT > 12 + , typename M = nil_t + , typename N = nil_t + , typename O = nil_t + +#endif +#endif +#endif +#endif + + , typename NU = nil_t // Not used +> +struct tuple; + +/////////////////////////////////////////////////////////////////////////////// +// +// tuple_index +// +// This class wraps an integer in a type to be used for indexing +// the Nth element in a tuple. See tuple operator[]. Some +// predefined names are provided in sub-namespace +// tuple_index_names. +// +/////////////////////////////////////////////////////////////////////////////// +template <int N> +struct tuple_index {}; + +////////////////////////////////// +namespace tuple_index_names { + + tuple_index<0> const _1 = tuple_index<0>(); + tuple_index<1> const _2 = tuple_index<1>(); + tuple_index<2> const _3 = tuple_index<2>(); + +#if PHOENIX_LIMIT > 3 + tuple_index<3> const _4 = tuple_index<3>(); + tuple_index<4> const _5 = tuple_index<4>(); + tuple_index<5> const _6 = tuple_index<5>(); + +#if PHOENIX_LIMIT > 6 + tuple_index<6> const _7 = tuple_index<6>(); + tuple_index<7> const _8 = tuple_index<7>(); + tuple_index<8> const _9 = tuple_index<8>(); + +#if PHOENIX_LIMIT > 9 + tuple_index<9> const _10 = tuple_index<9>(); + tuple_index<10> const _11 = tuple_index<10>(); + tuple_index<11> const _12 = tuple_index<11>(); + +#if PHOENIX_LIMIT > 12 + tuple_index<12> const _13 = tuple_index<12>(); + tuple_index<13> const _14 = tuple_index<13>(); + tuple_index<14> const _15 = tuple_index<14>(); + +#endif +#endif +#endif +#endif +} + +/////////////////////////////////////////////////////////////////////////////// +// +// tuple_common class +// +/////////////////////////////////////////////////////////////////////////////// +template <typename DerivedT> +struct tuple_base { + + typedef nil_t a_type; + typedef nil_t b_type; + typedef nil_t c_type; + +#if PHOENIX_LIMIT > 3 + typedef nil_t d_type; + typedef nil_t e_type; + typedef nil_t f_type; + +#if PHOENIX_LIMIT > 6 + typedef nil_t g_type; + typedef nil_t h_type; + typedef nil_t i_type; + +#if PHOENIX_LIMIT > 9 + typedef nil_t j_type; + typedef nil_t k_type; + typedef nil_t l_type; + +#if PHOENIX_LIMIT > 12 + typedef nil_t m_type; + typedef nil_t n_type; + typedef nil_t o_type; + +#endif +#endif +#endif +#endif + + template <int N> + typename tuple_element<N, DerivedT>::crtype + operator[](tuple_index<N>) const + { + return tuple_element<N, DerivedT> + ::get(*static_cast<DerivedT const*>(this)); + } + + template <int N> + typename tuple_element<N, DerivedT>::rtype + operator[](tuple_index<N>) + { + return tuple_element<N, DerivedT> + ::get(*static_cast<DerivedT*>(this)); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// tuple <0 member> class +// +/////////////////////////////////////////////////////////////////////////////// +template <> +struct tuple<> +: public tuple_base<tuple<> > { + + BOOST_STATIC_CONSTANT(int, length = 0); +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// tuple <1 member> class +// +/////////////////////////////////////////////////////////////////////////////// +template <typename A> +struct tuple<A, nil_t, nil_t, +#if PHOENIX_LIMIT > 3 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 6 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif +#endif +#endif + nil_t // Unused +> +: public tuple_base<tuple<A> > { + + BOOST_STATIC_CONSTANT(int, length = 1); + typedef A a_type; + + tuple() {} + + tuple( + typename call_traits<A>::param_type a_ + ): a(a_) {} + + template <typename TupleT> + tuple(TupleT const& init) + : a(init[tuple_index<0>()]) + { BOOST_STATIC_ASSERT(TupleT::length == length); } + + A a; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// tuple <2 member> class +// +/////////////////////////////////////////////////////////////////////////////// +template <typename A, typename B> +struct tuple<A, B, nil_t, +#if PHOENIX_LIMIT > 3 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 6 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif +#endif +#endif + nil_t // Unused +> +: public tuple_base<tuple<A, B> > { + + BOOST_STATIC_CONSTANT(int, length = 2); + typedef A a_type; typedef B b_type; + + tuple() {} + + tuple( + typename call_traits<A>::param_type a_, + typename call_traits<B>::param_type b_ + ): a(a_), b(b_) {} + + template <typename TupleT> + tuple(TupleT const& init) + : a(init[tuple_index<0>()]), b(init[tuple_index<1>()]) + { BOOST_STATIC_ASSERT(TupleT::length == length); } + + A a; B b; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// tuple <3 member> class +// +/////////////////////////////////////////////////////////////////////////////// +template <typename A, typename B, typename C> +struct tuple<A, B, C, +#if PHOENIX_LIMIT > 3 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 6 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif +#endif +#endif + nil_t // Unused +> +: public tuple_base<tuple<A, B, C> > { + + BOOST_STATIC_CONSTANT(int, length = 3); + typedef A a_type; typedef B b_type; + typedef C c_type; + + tuple() {} + + tuple( + typename call_traits<A>::param_type a_, + typename call_traits<B>::param_type b_, + typename call_traits<C>::param_type c_ + ): a(a_), b(b_), c(c_) {} + + template <typename TupleT> + tuple(TupleT const& init) + : a(init[tuple_index<0>()]), b(init[tuple_index<1>()]), + c(init[tuple_index<2>()]) + { BOOST_STATIC_ASSERT(TupleT::length == length); } + + A a; B b; C c; +}; + +#if PHOENIX_LIMIT > 3 +/////////////////////////////////////////////////////////////////////////////// +// +// tuple <4 member> class +// +/////////////////////////////////////////////////////////////////////////////// +template <typename A, typename B, typename C, typename D> +struct tuple<A, B, C, D, nil_t, nil_t, +#if PHOENIX_LIMIT > 6 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif +#endif + nil_t // Unused +> +: public tuple_base<tuple<A, B, C, D> > { + + BOOST_STATIC_CONSTANT(int, length = 4); + typedef A a_type; typedef B b_type; + typedef C c_type; typedef D d_type; + + tuple() {} + + tuple( + typename call_traits<A>::param_type a_, + typename call_traits<B>::param_type b_, + typename call_traits<C>::param_type c_, + typename call_traits<D>::param_type d_ + ): a(a_), b(b_), c(c_), d(d_) {} + + template <typename TupleT> + tuple(TupleT const& init) + : a(init[tuple_index<0>()]), b(init[tuple_index<1>()]), + c(init[tuple_index<2>()]), d(init[tuple_index<3>()]) + { BOOST_STATIC_ASSERT(TupleT::length == length); } + + A a; B b; C c; D d; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// tuple <5 member> class +// +/////////////////////////////////////////////////////////////////////////////// +template <typename A, typename B, typename C, typename D, typename E> +struct tuple<A, B, C, D, E, nil_t, +#if PHOENIX_LIMIT > 6 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif +#endif + nil_t // Unused +> +: public tuple_base<tuple<A, B, C, D, E> > { + + BOOST_STATIC_CONSTANT(int, length = 5); + typedef A a_type; typedef B b_type; + typedef C c_type; typedef D d_type; + typedef E e_type; + + tuple() {} + + tuple( + typename call_traits<A>::param_type a_, + typename call_traits<B>::param_type b_, + typename call_traits<C>::param_type c_, + typename call_traits<D>::param_type d_, + typename call_traits<E>::param_type e_ + ): a(a_), b(b_), c(c_), d(d_), e(e_) {} + + template <typename TupleT> + tuple(TupleT const& init) + : a(init[tuple_index<0>()]), b(init[tuple_index<1>()]), + c(init[tuple_index<2>()]), d(init[tuple_index<3>()]), + e(init[tuple_index<4>()]) + { BOOST_STATIC_ASSERT(TupleT::length == length); } + + A a; B b; C c; D d; E e; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// tuple <6 member> class +// +/////////////////////////////////////////////////////////////////////////////// +template < + typename A, typename B, typename C, typename D, typename E, + typename F> +struct tuple<A, B, C, D, E, F, +#if PHOENIX_LIMIT > 6 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif +#endif + nil_t // Unused +> +: public tuple_base<tuple<A, B, C, D, E, F> > { + + BOOST_STATIC_CONSTANT(int, length = 6); + typedef A a_type; typedef B b_type; + typedef C c_type; typedef D d_type; + typedef E e_type; typedef F f_type; + + tuple() {} + + tuple( + typename call_traits<A>::param_type a_, + typename call_traits<B>::param_type b_, + typename call_traits<C>::param_type c_, + typename call_traits<D>::param_type d_, + typename call_traits<E>::param_type e_, + typename call_traits<F>::param_type f_ + ): a(a_), b(b_), c(c_), d(d_), e(e_), + f(f_) {} + + template <typename TupleT> + tuple(TupleT const& init) + : a(init[tuple_index<0>()]), b(init[tuple_index<1>()]), + c(init[tuple_index<2>()]), d(init[tuple_index<3>()]), + e(init[tuple_index<4>()]), f(init[tuple_index<5>()]) + { BOOST_STATIC_ASSERT(TupleT::length == length); } + + A a; B b; C c; D d; E e; + F f; +}; + +#if PHOENIX_LIMIT > 6 +/////////////////////////////////////////////////////////////////////////////// +// +// tuple <7 member> class +// +/////////////////////////////////////////////////////////////////////////////// +template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G> +struct tuple<A, B, C, D, E, F, G, nil_t, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif + nil_t // Unused +> +: public tuple_base<tuple<A, B, C, D, E, F, G> > { + + BOOST_STATIC_CONSTANT(int, length = 7); + typedef A a_type; typedef B b_type; + typedef C c_type; typedef D d_type; + typedef E e_type; typedef F f_type; + typedef G g_type; + + tuple() {} + + tuple( + typename call_traits<A>::param_type a_, + typename call_traits<B>::param_type b_, + typename call_traits<C>::param_type c_, + typename call_traits<D>::param_type d_, + typename call_traits<E>::param_type e_, + typename call_traits<F>::param_type f_, + typename call_traits<G>::param_type g_ + ): a(a_), b(b_), c(c_), d(d_), e(e_), + f(f_), g(g_) {} + + template <typename TupleT> + tuple(TupleT const& init) + : a(init[tuple_index<0>()]), b(init[tuple_index<1>()]), + c(init[tuple_index<2>()]), d(init[tuple_index<3>()]), + e(init[tuple_index<4>()]), f(init[tuple_index<5>()]), + g(init[tuple_index<6>()]) + { BOOST_STATIC_ASSERT(TupleT::length == length); } + + A a; B b; C c; D d; E e; + F f; G g; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// tuple <8 member> class +// +/////////////////////////////////////////////////////////////////////////////// +template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H> +struct tuple<A, B, C, D, E, F, G, H, nil_t, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif + nil_t // Unused +> +: public tuple_base<tuple<A, B, C, D, E, F, G, H> > { + + BOOST_STATIC_CONSTANT(int, length = 8); + typedef A a_type; typedef B b_type; + typedef C c_type; typedef D d_type; + typedef E e_type; typedef F f_type; + typedef G g_type; typedef H h_type; + + tuple() {} + + tuple( + typename call_traits<A>::param_type a_, + typename call_traits<B>::param_type b_, + typename call_traits<C>::param_type c_, + typename call_traits<D>::param_type d_, + typename call_traits<E>::param_type e_, + typename call_traits<F>::param_type f_, + typename call_traits<G>::param_type g_, + typename call_traits<H>::param_type h_ + ): a(a_), b(b_), c(c_), d(d_), e(e_), + f(f_), g(g_), h(h_) {} + + template <typename TupleT> + tuple(TupleT const& init) + : a(init[tuple_index<0>()]), b(init[tuple_index<1>()]), + c(init[tuple_index<2>()]), d(init[tuple_index<3>()]), + e(init[tuple_index<4>()]), f(init[tuple_index<5>()]), + g(init[tuple_index<6>()]), h(init[tuple_index<7>()]) + { BOOST_STATIC_ASSERT(TupleT::length == length); } + + A a; B b; C c; D d; E e; + F f; G g; H h; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// tuple <9 member> class +// +/////////////////////////////////////////////////////////////////////////////// +template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I> +struct tuple<A, B, C, D, E, F, G, H, I, +#if PHOENIX_LIMIT > 9 + nil_t, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif +#endif + nil_t // Unused +> +: public tuple_base<tuple<A, B, C, D, E, F, G, H, I> > { + + BOOST_STATIC_CONSTANT(int, length = 9); + typedef A a_type; typedef B b_type; + typedef C c_type; typedef D d_type; + typedef E e_type; typedef F f_type; + typedef G g_type; typedef H h_type; + typedef I i_type; + + tuple() {} + + tuple( + typename call_traits<A>::param_type a_, + typename call_traits<B>::param_type b_, + typename call_traits<C>::param_type c_, + typename call_traits<D>::param_type d_, + typename call_traits<E>::param_type e_, + typename call_traits<F>::param_type f_, + typename call_traits<G>::param_type g_, + typename call_traits<H>::param_type h_, + typename call_traits<I>::param_type i_ + ): a(a_), b(b_), c(c_), d(d_), e(e_), + f(f_), g(g_), h(h_), i(i_) {} + + template <typename TupleT> + tuple(TupleT const& init) + : a(init[tuple_index<0>()]), b(init[tuple_index<1>()]), + c(init[tuple_index<2>()]), d(init[tuple_index<3>()]), + e(init[tuple_index<4>()]), f(init[tuple_index<5>()]), + g(init[tuple_index<6>()]), h(init[tuple_index<7>()]), + i(init[tuple_index<8>()]) + { BOOST_STATIC_ASSERT(TupleT::length == length); } + + A a; B b; C c; D d; E e; + F f; G g; H h; I i; +}; + +#if PHOENIX_LIMIT > 9 +/////////////////////////////////////////////////////////////////////////////// +// +// tuple <10 member> class +// +/////////////////////////////////////////////////////////////////////////////// +template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J> +struct tuple<A, B, C, D, E, F, G, H, I, J, nil_t, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif + nil_t // Unused +> +: public tuple_base<tuple<A, B, C, D, E, F, G, H, I, J> > { + + BOOST_STATIC_CONSTANT(int, length = 10); + typedef A a_type; typedef B b_type; + typedef C c_type; typedef D d_type; + typedef E e_type; typedef F f_type; + typedef G g_type; typedef H h_type; + typedef I i_type; typedef J j_type; + + tuple() {} + + tuple( + typename call_traits<A>::param_type a_, + typename call_traits<B>::param_type b_, + typename call_traits<C>::param_type c_, + typename call_traits<D>::param_type d_, + typename call_traits<E>::param_type e_, + typename call_traits<F>::param_type f_, + typename call_traits<G>::param_type g_, + typename call_traits<H>::param_type h_, + typename call_traits<I>::param_type i_, + typename call_traits<J>::param_type j_ + ): a(a_), b(b_), c(c_), d(d_), e(e_), + f(f_), g(g_), h(h_), i(i_), j(j_) {} + + template <typename TupleT> + tuple(TupleT const& init) + : a(init[tuple_index<0>()]), b(init[tuple_index<1>()]), + c(init[tuple_index<2>()]), d(init[tuple_index<3>()]), + e(init[tuple_index<4>()]), f(init[tuple_index<5>()]), + g(init[tuple_index<6>()]), h(init[tuple_index<7>()]), + i(init[tuple_index<8>()]), j(init[tuple_index<9>()]) + { BOOST_STATIC_ASSERT(TupleT::length == length); } + + A a; B b; C c; D d; E e; + F f; G g; H h; I i; J j; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// tuple <11 member> class +// +/////////////////////////////////////////////////////////////////////////////// +template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K> +struct tuple<A, B, C, D, E, F, G, H, I, J, K, nil_t, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif + nil_t // Unused +> +: public tuple_base<tuple<A, B, C, D, E, F, G, H, I, J, K> > { + + BOOST_STATIC_CONSTANT(int, length = 11); + typedef A a_type; typedef B b_type; + typedef C c_type; typedef D d_type; + typedef E e_type; typedef F f_type; + typedef G g_type; typedef H h_type; + typedef I i_type; typedef J j_type; + typedef K k_type; + + tuple() {} + + tuple( + typename call_traits<A>::param_type a_, + typename call_traits<B>::param_type b_, + typename call_traits<C>::param_type c_, + typename call_traits<D>::param_type d_, + typename call_traits<E>::param_type e_, + typename call_traits<F>::param_type f_, + typename call_traits<G>::param_type g_, + typename call_traits<H>::param_type h_, + typename call_traits<I>::param_type i_, + typename call_traits<J>::param_type j_, + typename call_traits<K>::param_type k_ + ): a(a_), b(b_), c(c_), d(d_), e(e_), + f(f_), g(g_), h(h_), i(i_), j(j_), + k(k_) {} + + template <typename TupleT> + tuple(TupleT const& init) + : a(init[tuple_index<0>()]), b(init[tuple_index<1>()]), + c(init[tuple_index<2>()]), d(init[tuple_index<3>()]), + e(init[tuple_index<4>()]), f(init[tuple_index<5>()]), + g(init[tuple_index<6>()]), h(init[tuple_index<7>()]), + i(init[tuple_index<8>()]), j(init[tuple_index<9>()]), + k(init[tuple_index<10>()]) + { BOOST_STATIC_ASSERT(TupleT::length == length); } + + A a; B b; C c; D d; E e; + F f; G g; H h; I i; J j; + K k; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// tuple <12 member> class +// +/////////////////////////////////////////////////////////////////////////////// +template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L> +struct tuple<A, B, C, D, E, F, G, H, I, J, K, L, +#if PHOENIX_LIMIT > 12 + nil_t, nil_t, nil_t, +#endif + nil_t // Unused +> +: public tuple_base<tuple<A, B, C, D, E, F, G, H, I, J, K, L> > { + + BOOST_STATIC_CONSTANT(int, length = 12); + typedef A a_type; typedef B b_type; + typedef C c_type; typedef D d_type; + typedef E e_type; typedef F f_type; + typedef G g_type; typedef H h_type; + typedef I i_type; typedef J j_type; + typedef K k_type; typedef L l_type; + + tuple() {} + + tuple( + typename call_traits<A>::param_type a_, + typename call_traits<B>::param_type b_, + typename call_traits<C>::param_type c_, + typename call_traits<D>::param_type d_, + typename call_traits<E>::param_type e_, + typename call_traits<F>::param_type f_, + typename call_traits<G>::param_type g_, + typename call_traits<H>::param_type h_, + typename call_traits<I>::param_type i_, + typename call_traits<J>::param_type j_, + typename call_traits<K>::param_type k_, + typename call_traits<L>::param_type l_ + ): a(a_), b(b_), c(c_), d(d_), e(e_), + f(f_), g(g_), h(h_), i(i_), j(j_), + k(k_), l(l_) {} + + template <typename TupleT> + tuple(TupleT const& init) + : a(init[tuple_index<0>()]), b(init[tuple_index<1>()]), + c(init[tuple_index<2>()]), d(init[tuple_index<3>()]), + e(init[tuple_index<4>()]), f(init[tuple_index<5>()]), + g(init[tuple_index<6>()]), h(init[tuple_index<7>()]), + i(init[tuple_index<8>()]), j(init[tuple_index<9>()]), + k(init[tuple_index<10>()]), l(init[tuple_index<11>()]) + { BOOST_STATIC_ASSERT(TupleT::length == length); } + + A a; B b; C c; D d; E e; + F f; G g; H h; I i; J j; + K k; L l; +}; + +#if PHOENIX_LIMIT > 12 +/////////////////////////////////////////////////////////////////////////////// +// +// tuple <13 member> class +// +/////////////////////////////////////////////////////////////////////////////// +template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M> +struct tuple<A, B, C, D, E, F, G, H, I, J, K, L, M, nil_t, nil_t, nil_t> +: public tuple_base< + tuple<A, B, C, D, E, F, G, H, I, J, K, L, M> > { + + BOOST_STATIC_CONSTANT(int, length = 13); + typedef A a_type; typedef B b_type; + typedef C c_type; typedef D d_type; + typedef E e_type; typedef F f_type; + typedef G g_type; typedef H h_type; + typedef I i_type; typedef J j_type; + typedef K k_type; typedef L l_type; + typedef M m_type; + + tuple() {} + + tuple( + typename call_traits<A>::param_type a_, + typename call_traits<B>::param_type b_, + typename call_traits<C>::param_type c_, + typename call_traits<D>::param_type d_, + typename call_traits<E>::param_type e_, + typename call_traits<F>::param_type f_, + typename call_traits<G>::param_type g_, + typename call_traits<H>::param_type h_, + typename call_traits<I>::param_type i_, + typename call_traits<J>::param_type j_, + typename call_traits<K>::param_type k_, + typename call_traits<L>::param_type l_, + typename call_traits<M>::param_type m_ + ): a(a_), b(b_), c(c_), d(d_), e(e_), + f(f_), g(g_), h(h_), i(i_), j(j_), + k(k_), l(l_), m(m_) {} + + template <typename TupleT> + tuple(TupleT const& init) + : a(init[tuple_index<0>()]), b(init[tuple_index<1>()]), + c(init[tuple_index<2>()]), d(init[tuple_index<3>()]), + e(init[tuple_index<4>()]), f(init[tuple_index<5>()]), + g(init[tuple_index<6>()]), h(init[tuple_index<7>()]), + i(init[tuple_index<8>()]), j(init[tuple_index<9>()]), + k(init[tuple_index<10>()]), l(init[tuple_index<11>()]), + m(init[tuple_index<12>()]) + { BOOST_STATIC_ASSERT(TupleT::length == length); } + + A a; B b; C c; D d; E e; + F f; G g; H h; I i; J j; + K k; L l; M m; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// tuple <14 member> class +// +/////////////////////////////////////////////////////////////////////////////// +template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M, typename N> +struct tuple<A, B, C, D, E, F, G, H, I, J, K, L, M, N, nil_t, nil_t> +: public tuple_base< + tuple<A, B, C, D, E, F, G, H, I, J, K, L, M, N> > { + + BOOST_STATIC_CONSTANT(int, length = 14); + typedef A a_type; typedef B b_type; + typedef C c_type; typedef D d_type; + typedef E e_type; typedef F f_type; + typedef G g_type; typedef H h_type; + typedef I i_type; typedef J j_type; + typedef K k_type; typedef L l_type; + typedef M m_type; typedef N n_type; + + tuple() {} + + tuple( + typename call_traits<A>::param_type a_, + typename call_traits<B>::param_type b_, + typename call_traits<C>::param_type c_, + typename call_traits<D>::param_type d_, + typename call_traits<E>::param_type e_, + typename call_traits<F>::param_type f_, + typename call_traits<G>::param_type g_, + typename call_traits<H>::param_type h_, + typename call_traits<I>::param_type i_, + typename call_traits<J>::param_type j_, + typename call_traits<K>::param_type k_, + typename call_traits<L>::param_type l_, + typename call_traits<M>::param_type m_, + typename call_traits<N>::param_type n_ + ): a(a_), b(b_), c(c_), d(d_), e(e_), + f(f_), g(g_), h(h_), i(i_), j(j_), + k(k_), l(l_), m(m_), n(n_) {} + + template <typename TupleT> + tuple(TupleT const& init) + : a(init[tuple_index<0>()]), b(init[tuple_index<1>()]), + c(init[tuple_index<2>()]), d(init[tuple_index<3>()]), + e(init[tuple_index<4>()]), f(init[tuple_index<5>()]), + g(init[tuple_index<6>()]), h(init[tuple_index<7>()]), + i(init[tuple_index<8>()]), j(init[tuple_index<9>()]), + k(init[tuple_index<10>()]), l(init[tuple_index<11>()]), + m(init[tuple_index<12>()]), n(init[tuple_index<13>()]) + { BOOST_STATIC_ASSERT(TupleT::length == length); } + + A a; B b; C c; D d; E e; + F f; G g; H h; I i; J j; + K k; L l; M m; N n; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// tuple <15 member> class +// +/////////////////////////////////////////////////////////////////////////////// +template < + typename A, typename B, typename C, typename D, typename E, + typename F, typename G, typename H, typename I, typename J, + typename K, typename L, typename M, typename N, typename O> +struct tuple<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, nil_t> +: public tuple_base< + tuple<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O> > { + + BOOST_STATIC_CONSTANT(int, length = 15); + typedef A a_type; typedef B b_type; + typedef C c_type; typedef D d_type; + typedef E e_type; typedef F f_type; + typedef G g_type; typedef H h_type; + typedef I i_type; typedef J j_type; + typedef K k_type; typedef L l_type; + typedef M m_type; typedef N n_type; + typedef O o_type; + + tuple() {} + + tuple( + typename call_traits<A>::param_type a_, + typename call_traits<B>::param_type b_, + typename call_traits<C>::param_type c_, + typename call_traits<D>::param_type d_, + typename call_traits<E>::param_type e_, + typename call_traits<F>::param_type f_, + typename call_traits<G>::param_type g_, + typename call_traits<H>::param_type h_, + typename call_traits<I>::param_type i_, + typename call_traits<J>::param_type j_, + typename call_traits<K>::param_type k_, + typename call_traits<L>::param_type l_, + typename call_traits<M>::param_type m_, + typename call_traits<N>::param_type n_, + typename call_traits<O>::param_type o_ + ): a(a_), b(b_), c(c_), d(d_), e(e_), + f(f_), g(g_), h(h_), i(i_), j(j_), + k(k_), l(l_), m(m_), n(n_), o(o_) {} + + template <typename TupleT> + tuple(TupleT const& init) + : a(init[tuple_index<0>()]), b(init[tuple_index<1>()]), + c(init[tuple_index<2>()]), d(init[tuple_index<3>()]), + e(init[tuple_index<4>()]), f(init[tuple_index<5>()]), + g(init[tuple_index<6>()]), h(init[tuple_index<7>()]), + i(init[tuple_index<8>()]), j(init[tuple_index<9>()]), + k(init[tuple_index<10>()]), l(init[tuple_index<11>()]), + m(init[tuple_index<12>()]), n(init[tuple_index<13>()]), + o(init[tuple_index<14>()]) + { BOOST_STATIC_ASSERT(TupleT::length == length); } + + A a; B b; C c; D d; E e; + F f; G g; H h; I i; J j; + K k; L l; M m; N n; O o; +}; + +#endif +#endif +#endif +#endif + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(pop) +#endif + +/////////////////////////////////////////////////////////////////////////////// +} // namespace phoenix + +#endif diff --git a/boost/spirit/home/classic/symbols.hpp b/boost/spirit/home/classic/symbols.hpp new file mode 100644 index 0000000000..d65d70b2a7 --- /dev/null +++ b/boost/spirit/home/classic/symbols.hpp @@ -0,0 +1,21 @@ +/*============================================================================= + Copyright (c) 2001-2003 Joel de Guzman + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_SYMBOLS_MAIN_HPP) +#define BOOST_SPIRIT_SYMBOLS_MAIN_HPP + +#include <boost/spirit/home/classic/version.hpp> + +/////////////////////////////////////////////////////////////////////////////// +// +// Master header for Spirit.Symbols +// +/////////////////////////////////////////////////////////////////////////////// + +#include <boost/spirit/home/classic/symbols/symbols.hpp> + +#endif // !defined(BOOST_SPIRIT_SYMBOLS_MAIN_HPP) diff --git a/boost/spirit/home/classic/symbols/impl/symbols.ipp b/boost/spirit/home/classic/symbols/impl/symbols.ipp new file mode 100644 index 0000000000..561341a16c --- /dev/null +++ b/boost/spirit/home/classic/symbols/impl/symbols.ipp @@ -0,0 +1,118 @@ +/*============================================================================= + 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_SPIRIT_SYMBOLS_IPP +#define BOOST_SPIRIT_SYMBOLS_IPP + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/spirit/home/classic/symbols/impl/tst.ipp> +#include <boost/detail/workaround.hpp> + +// MSVC: void warning about the use of 'this' pointer in constructors +#if defined(BOOST_MSVC) +#pragma warning(push) +#pragma warning(disable : 4355) +#endif + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// +// symbols class implementation +// +/////////////////////////////////////////////////////////////////////////////// +template <typename T, typename CharT, typename SetT> +inline symbols<T, CharT, SetT>::symbols() +: SetT() +, add(*this) +{ +} + +////////////////////////////////// +template <typename T, typename CharT, typename SetT> +symbols<T, CharT, SetT>::symbols(symbols const& other) +: SetT(other) +// Tru64 CXX seems to be confused by the explicit call of the default +// constructor and generates wrong code which invalidates the just contructed +// first base class in the line above. +#if !BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590041)) +, parser<symbols<T, CharT, SetT> >() +#endif +, add(*this) +{ +} + +////////////////////////////////// +template <typename T, typename CharT, typename SetT> +inline symbols<T, CharT, SetT>::~symbols() +{} + +////////////////////////////////// +template <typename T, typename CharT, typename SetT> +inline symbols<T, CharT, SetT>& +symbols<T, CharT, SetT>::operator=(symbols const& other) +{ + SetT::operator=(other); + return *this; +} + +////////////////////////////////// +template <typename T, typename CharT, typename SetT> +inline symbol_inserter<T, SetT> const& +symbols<T, CharT, SetT>::operator=(CharT const* str) +{ + return add, str; +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Symbol table utilities +// +/////////////////////////////////////////////////////////////////////////////// +template <typename T, typename CharT, typename SetT> +inline T* +find(symbols<T, CharT, SetT> const& table, CharT const* sym) +{ + CharT const* last = sym; + while (*last) + last++; + scanner<CharT const *> scan(sym, last); + T* result = table.find(scan); + return scan.at_end()? result: 0; +} + +////////////////////////////////// +template <typename T, typename CharT, typename SetT> +inline T* +add(symbols<T, CharT, SetT>& table, CharT const* sym, T const& data) +{ + CharT const* first = sym; + CharT const* last = sym; + while (*last) + last++; + scanner<CharT const *> scan(first, last); + if (table.find(scan) && scan.at_end()) + return 0; // symbol already contained in symbol table + table.add(sym, last, data); + first = sym; + return table.find(scan); // refind the inserted symbol +} + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#if defined(BOOST_MSVC) +#pragma warning(pop) +#endif + +#endif diff --git a/boost/spirit/home/classic/symbols/impl/tst.ipp b/boost/spirit/home/classic/symbols/impl/tst.ipp new file mode 100644 index 0000000000..1a4a0c1052 --- /dev/null +++ b/boost/spirit/home/classic/symbols/impl/tst.ipp @@ -0,0 +1,281 @@ +/*============================================================================= + 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_SPIRIT_TST_IPP +#define BOOST_SPIRIT_TST_IPP + +/////////////////////////////////////////////////////////////////////////////// +#include <memory> // for std::auto_ptr +#include <boost/spirit/home/classic/core/assert.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + namespace impl + { + +/////////////////////////////////////////////////////////////////////////////// +// +// tst class +// +// Ternary Search Tree implementation. The data structure is faster than +// hashing for many typical search problems especially when the search +// interface is iterator based. Searching for a string of length k in a +// ternary search tree with n strings will require at most O(log n+k) +// character comparisons. TSTs are many times faster than hash tables +// for unsuccessful searches since mismatches are discovered earlier +// after examining only a few characters. Hash tables always examine an +// entire key when searching. +// +// For details see http://www.cs.princeton.edu/~rs/strings/. +// +// *** This is a low level class and is +// not meant for public consumption *** +// +/////////////////////////////////////////////////////////////////////////////// + template <typename T, typename CharT> + struct tst_node + { + tst_node(CharT value_) + : value(value_) + , left(0) + , right(0) + { middle.link = 0; } + + ~tst_node() + { + delete left; + delete right; + if (value) + delete middle.link; + else + delete middle.data; + } + + tst_node* + clone() const + { + std::auto_ptr<tst_node> copy(new tst_node(value)); + + if (left) + copy->left = left->clone(); + if (right) + copy->right = right->clone(); + + if (value && middle.link) + { + copy->middle.link = middle.link->clone(); + } + else + { + std::auto_ptr<T> mid_data(new T(*middle.data)); + copy->middle.data = mid_data.release(); + } + + return copy.release(); + } + + union center { + + tst_node* link; + T* data; + }; + + CharT value; + tst_node* left; + center middle; + tst_node* right; + }; + + /////////////////////////////////////////////////////////////////////////// + template <typename T, typename CharT> + class tst + { + public: + + struct search_info + { + T* data; + std::size_t length; + }; + + tst() + : root(0) {} + + tst(tst const& other) + : root(other.root ? other.root->clone() : 0) {} + + ~tst() + { delete root; } + + tst& + operator=(tst const& other) + { + if (this != &other) + { + node_t* new_root = other.root ? other.root->clone() : 0; + delete root; + root = new_root; + } + return *this; + } + + template <typename IteratorT> + T* add(IteratorT first, IteratorT const& last, T const& data) + { + if (first == last) + return 0; + + node_t** np = &root; + CharT ch = *first; + + BOOST_SPIRIT_ASSERT((first == last || ch != 0) + && "Won't add string containing null character"); + + for (;;) + { + if (*np == 0 || ch == 0) + { + node_t* right = 0; + if (np != 0) + right = *np; + *np = new node_t(ch); + if (right) + (**np).right = right; + } + + if (ch < (**np).value) + { + np = &(**np).left; + } + else + { + if (ch == (**np).value) + { + if (ch == 0) + { + if ((**np).middle.data == 0) + { + (**np).middle.data = new T(data); + return (**np).middle.data; + } + else + { + // re-addition is disallowed + return 0; + } + } + ++first; + ch = (first == last) ? CharT(0) : *first; + BOOST_SPIRIT_ASSERT((first == last || ch != 0) + && "Won't add string containing null character"); + np = &(**np).middle.link; + } + else + { + np = &(**np).right; + } + } + } + } + + template <typename ScannerT> + search_info find(ScannerT const& scan) const + { + search_info result = { 0, 0 }; + if (scan.at_end()) { + return result; + } + + typedef typename ScannerT::iterator_t iterator_t; + node_t* np = root; + CharT ch = *scan; + iterator_t save = scan.first; + iterator_t latest = scan.first; + std::size_t latest_len = 0; + + while (np) + { + + if (ch < np->value) // => go left! + { + if (np->value == 0) + { + result.data = np->middle.data; + if (result.data) + { + latest = scan.first; + latest_len = result.length; + } + } + + np = np->left; + } + else if (ch == np->value) // => go middle! + { + // Matching the null character is not allowed. + if (np->value == 0) + { + result.data = np->middle.data; + if (result.data) + { + latest = scan.first; + latest_len = result.length; + } + break; + } + + ++scan; + ch = scan.at_end() ? CharT(0) : *scan; + np = np->middle.link; + ++result.length; + } + else // (ch > np->value) => go right! + { + if (np->value == 0) + { + result.data = np->middle.data; + if (result.data) + { + latest = scan.first; + latest_len = result.length; + } + } + + np = np->right; + } + } + + if (result.data == 0) + { + scan.first = save; + } + else + { + scan.first = latest; + result.length = latest_len; + } + return result; + } + + private: + + typedef tst_node<T, CharT> node_t; + node_t* root; + }; + +/////////////////////////////////////////////////////////////////////////////// + } // namespace impl + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#endif diff --git a/boost/spirit/home/classic/symbols/symbols.hpp b/boost/spirit/home/classic/symbols/symbols.hpp new file mode 100644 index 0000000000..8605585685 --- /dev/null +++ b/boost/spirit/home/classic/symbols/symbols.hpp @@ -0,0 +1,229 @@ +/*============================================================================= + Copyright (c) 2001-2003 Joel de Guzman + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#ifndef BOOST_SPIRIT_SYMBOLS_HPP +#define BOOST_SPIRIT_SYMBOLS_HPP + +/////////////////////////////////////////////////////////////////////////////// +#include <string> + +#include <boost/ref.hpp> + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/core/composite/directives.hpp> + +#include <boost/spirit/home/classic/symbols/symbols_fwd.hpp> + + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// +// symbols class +// +// This class implements a symbol table. The symbol table holds a +// dictionary of symbols where each symbol is a sequence of CharTs. +// The template class can work efficiently with 8, 16 and 32 bit +// characters. Mutable data of type T is associated with each +// symbol. +// +// The class is a parser. The parse member function returns +// additional information in the symbol_match class (see below). +// The additional data is a pointer to some data associated with +// the matching symbol. +// +// The actual set implementation is supplied by the SetT template +// parameter. By default, this uses the tst class (see tst.ipp). +// +// Symbols are added into the symbol table statically using the +// construct: +// +// sym = a, b, c, d ...; +// +// where sym is a symbol table and a..d are strings. Example: +// +// sym = "pineapple", "orange", "banana", "apple"; +// +// Alternatively, symbols may be added dynamically through the +// member functor 'add' (see symbol_inserter below). The member +// functor 'add' may be attached to a parser as a semantic action +// taking in a begin/end pair: +// +// p[sym.add] +// +// where p is a parser (and sym is a symbol table). On success, +// the matching portion of the input is added to the symbol table. +// +// 'add' may also be used to directly initialize data. Examples: +// +// sym.add("hello", 1)("crazy", 2)("world", 3); +// +/////////////////////////////////////////////////////////////////////////////// +template <typename T, typename CharT, typename SetT> +class symbols +: private SetT +, public parser<symbols<T, CharT, SetT> > +{ +public: + + typedef parser<symbols<T, CharT, SetT> > parser_base_t; + typedef symbols<T, CharT, SetT> self_t; + typedef self_t const& embed_t; + typedef T symbol_data_t; + typedef boost::reference_wrapper<T> symbol_ref_t; + + symbols(); + symbols(symbols const& other); + ~symbols(); + + symbols& + operator=(symbols const& other); + + symbol_inserter<T, SetT> const& + operator=(CharT const* str); + + template <typename ScannerT> + struct result + { + typedef typename match_result<ScannerT, symbol_ref_t>::type type; + }; + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse_main(ScannerT const& scan) const + { + typedef typename ScannerT::iterator_t iterator_t; + iterator_t first = scan.first; + typename SetT::search_info result = SetT::find(scan); + + if (result.data) + return scan. + create_match( + result.length, + symbol_ref_t(*result.data), + first, + scan.first); + else + return scan.no_match(); + } + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename parser_result<self_t, ScannerT>::type result_t; + return impl::implicit_lexeme_parse<result_t> + (*this, scan, scan); + } + + template < typename ScannerT > + T* find(ScannerT const& scan) const + { return SetT::find(scan).data; } + + symbol_inserter<T, SetT> const add; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// Symbol table utilities +// +// add +// +// adds a symbol 'sym' (string) to a symbol table 'table' plus an +// optional data 'data' associated with the symbol. Returns a pointer to +// the data associated with the symbol or NULL if add failed (e.g. when +// the symbol is already added before). +// +// find +// +// finds a symbol 'sym' (string) from a symbol table 'table'. Returns a +// pointer to the data associated with the symbol or NULL if not found +// +/////////////////////////////////////////////////////////////////////////////// +template <typename T, typename CharT, typename SetT> +T* add(symbols<T, CharT, SetT>& table, CharT const* sym, T const& data = T()); + +template <typename T, typename CharT, typename SetT> +T* find(symbols<T, CharT, SetT> const& table, CharT const* sym); + +/////////////////////////////////////////////////////////////////////////////// +// +// symbol_inserter class +// +// The symbols class holds an instance of this class named 'add'. +// This can be called directly just like a member function, +// passing in a first/last iterator and optional data: +// +// sym.add(first, last, data); +// +// Or, passing in a C string and optional data: +// +// sym.add(c_string, data); +// +// where sym is a symbol table. The 'data' argument is optional. +// This may also be used as a semantic action since it conforms +// to the action interface (see action.hpp): +// +// p[sym.add] +// +/////////////////////////////////////////////////////////////////////////////// +template <typename T, typename SetT> +class symbol_inserter +{ +public: + + symbol_inserter(SetT& set_) + : set(set_) {} + + typedef symbol_inserter const & result_type; + + template <typename IteratorT> + symbol_inserter const& + operator()(IteratorT first, IteratorT const& last, T const& data = T()) const + { + set.add(first, last, data); + return *this; + } + + template <typename CharT> + symbol_inserter const& + operator()(CharT const* str, T const& data = T()) const + { + CharT const* last = str; + while (*last) + last++; + set.add(str, last, data); + return *this; + } + + template <typename CharT> + symbol_inserter const& + operator,(CharT const* str) const + { + CharT const* last = str; + while (*last) + last++; + set.add(str, last, T()); + return *this; + } + +private: + + SetT& set; +}; + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#include <boost/spirit/home/classic/symbols/impl/symbols.ipp> +#endif diff --git a/boost/spirit/home/classic/symbols/symbols_fwd.hpp b/boost/spirit/home/classic/symbols/symbols_fwd.hpp new file mode 100644 index 0000000000..402c319aed --- /dev/null +++ b/boost/spirit/home/classic/symbols/symbols_fwd.hpp @@ -0,0 +1,39 @@ +/*============================================================================= + Copyright (c) 2006 Tobias Schwinger + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_SYMBOLS_FWD_HPP) +#define BOOST_SPIRIT_SYMBOLS_FWD_HPP + +#include <boost/spirit/home/classic/namespace.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + namespace impl + { + template <typename CharT, typename T> + class tst; + } + + template + < + typename T = int, + typename CharT = char, + typename SetT = impl::tst<T, CharT> + > + class symbols; + + template <typename T, typename SetT> + class symbol_inserter; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + diff --git a/boost/spirit/home/classic/symbols/typeof.hpp b/boost/spirit/home/classic/symbols/typeof.hpp new file mode 100644 index 0000000000..c1631102a9 --- /dev/null +++ b/boost/spirit/home/classic/symbols/typeof.hpp @@ -0,0 +1,25 @@ +/*============================================================================= + Copyright (c) 2006 Tobias Schwinger + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_SYMBOLS_TYPEOF_HPP) +#define BOOST_SPIRIT_SYMBOLS_TYPEOF_HPP + +#include <boost/typeof/typeof.hpp> + +#include <boost/spirit/home/classic/symbols/symbols_fwd.hpp> + +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::symbols,3) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::symbol_inserter,2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::impl::tst,2) + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::symbols,2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::symbols,1) + +#endif + diff --git a/boost/spirit/home/classic/tree/ast.hpp b/boost/spirit/home/classic/tree/ast.hpp new file mode 100644 index 0000000000..0aa59f6dc7 --- /dev/null +++ b/boost/spirit/home/classic/tree/ast.hpp @@ -0,0 +1,387 @@ +/*============================================================================= + Copyright (c) 2001-2003 Daniel Nuffer + Copyright (c) 2001-2007 Hartmut Kaiser + 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_TREE_AST_HPP +#define BOOST_SPIRIT_TREE_AST_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/tree/common.hpp> +#include <boost/spirit/home/classic/core/scanner/scanner.hpp> + +#include <boost/spirit/home/classic/tree/ast_fwd.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +////////////////////////////////// +// ast_match_policy is simply an id so the correct specialization of +// tree_policy can be found. +template < + typename IteratorT, + typename NodeFactoryT, + typename T +> +struct ast_match_policy : + public common_tree_match_policy< + ast_match_policy<IteratorT, NodeFactoryT, T>, + IteratorT, + NodeFactoryT, + ast_tree_policy< + ast_match_policy<IteratorT, NodeFactoryT, T>, + NodeFactoryT, + T + >, + T + > +{ + typedef + common_tree_match_policy< + ast_match_policy<IteratorT, NodeFactoryT, T>, + IteratorT, + NodeFactoryT, + ast_tree_policy< + ast_match_policy<IteratorT, NodeFactoryT, T>, + NodeFactoryT, + T + >, + T + > + common_tree_match_policy_; + + ast_match_policy() + { + } + + template <typename PolicyT> + ast_match_policy(PolicyT const & policies) + : common_tree_match_policy_(policies) + { + } +}; + +////////////////////////////////// +template <typename MatchPolicyT, typename NodeFactoryT, typename T> +struct ast_tree_policy : + public common_tree_tree_policy<MatchPolicyT, NodeFactoryT> +{ + typedef typename MatchPolicyT::match_t match_t; + typedef typename MatchPolicyT::iterator_t iterator_t; + + template<typename MatchAT, typename MatchBT> + static void concat(MatchAT& a, MatchBT const& b) + { + BOOST_SPIRIT_ASSERT(a && b); + +#if defined(BOOST_SPIRIT_DEBUG) && \ + (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES) + BOOST_SPIRIT_DEBUG_OUT << "\n>>>AST concat. a = " << a << + "\n\tb = " << b << "<<<\n"; +#endif + typedef typename tree_match<iterator_t, NodeFactoryT, T>::container_t + container_t; + + // test for size() is nessecary, because no_tree_gen_node leaves a.trees + // and/or b.trees empty + if (0 != b.trees.size() && b.trees.begin()->value.is_root()) + { + BOOST_SPIRIT_ASSERT(b.trees.size() == 1); + + container_t tmp; + std::swap(a.trees, tmp); // save a into tmp + std::swap(b.trees, a.trees); // make b.trees[0] be new root (a.trees[0]) + container_t* pnon_root_trees = &a.trees; + while (pnon_root_trees->size() > 0 && + pnon_root_trees->begin()->value.is_root()) + { + pnon_root_trees = & pnon_root_trees->begin()->children; + } + pnon_root_trees->insert(pnon_root_trees->begin(), + tmp.begin(), tmp.end()); + } + else if (0 != a.trees.size() && a.trees.begin()->value.is_root()) + { + BOOST_SPIRIT_ASSERT(a.trees.size() == 1); + +#if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES) + a.trees.begin()->children.reserve(a.trees.begin()->children.size() + b.trees.size()); +#endif + std::copy(b.trees.begin(), + b.trees.end(), + std::back_insert_iterator<container_t>( + a.trees.begin()->children)); + } + else + { +#if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES) + a.trees.reserve(a.trees.size() + b.trees.size()); +#endif + std::copy(b.trees.begin(), + b.trees.end(), + std::back_insert_iterator<container_t>(a.trees)); + } + +#if defined(BOOST_SPIRIT_DEBUG) && \ + (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES) + BOOST_SPIRIT_DEBUG_OUT << ">>>after AST concat. a = " << a << "<<<\n\n"; +#endif + + return; + } + + template <typename MatchT, typename Iterator1T, typename Iterator2T> + static void group_match(MatchT& m, parser_id const& id, + Iterator1T const& first, Iterator2T const& last) + { + if (!m) + return; + + typedef typename tree_match<iterator_t, NodeFactoryT, T>::container_t + container_t; + typedef typename container_t::iterator cont_iterator_t; + typedef typename NodeFactoryT::template factory<iterator_t> factory_t; + + if (m.trees.size() == 1 +#ifdef BOOST_SPIRIT_NO_TREE_NODE_COLLAPSING + && !(id.to_long() && m.trees.begin()->value.id().to_long()) +#endif + ) + { + // set rule_id's. There may have been multiple nodes created. + // Because of root_node[] they may be left-most children of the top + // node. + container_t* punset_id = &m.trees; + while (punset_id->size() > 0 && + punset_id->begin()->value.id() == 0) + { + punset_id->begin()->value.id(id); + punset_id = &punset_id->begin()->children; + } + + m.trees.begin()->value.is_root(false); + } + else + { + match_t newmatch(m.length(), + m.trees.empty() ? + factory_t::empty_node() : + factory_t::create_node(first, last, false)); + + std::swap(newmatch.trees.begin()->children, m.trees); + // set this node and all it's unset children's rule_id + newmatch.trees.begin()->value.id(id); + for (cont_iterator_t i = newmatch.trees.begin(); + i != newmatch.trees.end(); + ++i) + { + if (i->value.id() == 0) + i->value.id(id); + } + m = newmatch; + } + } + + template <typename FunctorT, typename MatchT> + static void apply_op_to_match(FunctorT const& op, MatchT& m) + { + op(m); + } +}; + +namespace impl { + + template <typename IteratorT, typename NodeFactoryT, typename T> + struct tree_policy_selector<ast_match_policy<IteratorT, NodeFactoryT, T> > + { + typedef ast_tree_policy< + ast_match_policy<IteratorT, NodeFactoryT, T>, + NodeFactoryT, + T + > type; + }; + +} // namespace impl + + +////////////////////////////////// +struct gen_ast_node_parser_gen; + +template <typename T> +struct gen_ast_node_parser +: public unary<T, parser<gen_ast_node_parser<T> > > +{ + typedef gen_ast_node_parser<T> self_t; + typedef gen_ast_node_parser_gen parser_generator_t; + typedef unary_parser_category parser_category_t; + + gen_ast_node_parser(T const& a) + : unary<T, parser<gen_ast_node_parser<T> > >(a) {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename ScannerT::iteration_policy_t iteration_policy_t; + typedef typename ScannerT::match_policy_t::iterator_t iterator_t; + typedef typename ScannerT::match_policy_t::factory_t factory_t; + typedef ast_match_policy<iterator_t, factory_t> match_policy_t; + typedef typename ScannerT::action_policy_t action_policy_t; + typedef scanner_policies< + iteration_policy_t, + match_policy_t, + action_policy_t + > policies_t; + + return this->subject().parse(scan.change_policies(policies_t(scan))); + } +}; + +////////////////////////////////// +struct gen_ast_node_parser_gen +{ + template <typename T> + struct result { + + typedef gen_ast_node_parser<T> type; + }; + + template <typename T> + static gen_ast_node_parser<T> + generate(parser<T> const& s) + { + return gen_ast_node_parser<T>(s.derived()); + } + + template <typename T> + gen_ast_node_parser<T> + operator[](parser<T> const& s) const + { + return gen_ast_node_parser<T>(s.derived()); + } +}; + +////////////////////////////////// +const gen_ast_node_parser_gen gen_ast_node_d = gen_ast_node_parser_gen(); + + +////////////////////////////////// +struct root_node_op +{ + template <typename MatchT> + void operator()(MatchT& m) const + { + BOOST_SPIRIT_ASSERT(m.trees.size() > 0); + m.trees.begin()->value.is_root(true); + } +}; + +const node_parser_gen<root_node_op> root_node_d = + node_parser_gen<root_node_op>(); + +/////////////////////////////////////////////////////////////////////////////// +// +// Parse functions for ASTs +// +/////////////////////////////////////////////////////////////////////////////// +template < + typename AstFactoryT, typename IteratorT, typename ParserT, + typename SkipT +> +inline tree_parse_info<IteratorT, AstFactoryT> +ast_parse( + IteratorT const& first_, + IteratorT const& last_, + parser<ParserT> const& parser, + SkipT const& skip_, + AstFactoryT const & /*dummy_*/ = AstFactoryT()) +{ + typedef skip_parser_iteration_policy<SkipT> iter_policy_t; + typedef ast_match_policy<IteratorT, AstFactoryT> ast_match_policy_t; + typedef + scanner_policies<iter_policy_t, ast_match_policy_t> + scanner_policies_t; + typedef scanner<IteratorT, scanner_policies_t> scanner_t; + + iter_policy_t iter_policy(skip_); + scanner_policies_t policies(iter_policy); + IteratorT first = first_; + scanner_t scan(first, last_, policies); + tree_match<IteratorT, AstFactoryT> hit = parser.derived().parse(scan); + return tree_parse_info<IteratorT, AstFactoryT>( + first, hit, hit && (first == last_), hit.length(), hit.trees); +} + +////////////////////////////////// +template <typename IteratorT, typename ParserT, typename SkipT> +inline tree_parse_info<IteratorT> +ast_parse( + IteratorT const& first_, + IteratorT const& last_, + parser<ParserT> const& parser, + SkipT const& skip_) +{ + typedef node_val_data_factory<nil_t> default_factory_t; + return ast_parse(first_, last_, parser, skip_, default_factory_t()); +} + +////////////////////////////////// +template <typename IteratorT, typename ParserT> +inline tree_parse_info<IteratorT> +ast_parse( + IteratorT const& first_, + IteratorT const& last, + parser<ParserT> const& parser) +{ + typedef ast_match_policy<IteratorT> ast_match_policy_t; + IteratorT first = first_; + scanner< + IteratorT, + scanner_policies<iteration_policy, ast_match_policy_t> + > scan(first, last); + tree_match<IteratorT> hit = parser.derived().parse(scan); + return tree_parse_info<IteratorT>( + first, hit, hit && (first == last), hit.length(), hit.trees); +} + +////////////////////////////////// +template <typename CharT, typename ParserT, typename SkipT> +inline tree_parse_info<CharT const*> +ast_parse( + CharT const* str, + parser<ParserT> const& parser, + SkipT const& skip) +{ + CharT const* last = str; + while (*last) + last++; + return ast_parse(str, last, parser, skip); +} + +////////////////////////////////// +template <typename CharT, typename ParserT> +inline tree_parse_info<CharT const*> +ast_parse( + CharT const* str, + parser<ParserT> const& parser) +{ + CharT const* last = str; + while (*last) + { + last++; + } + return ast_parse(str, last, parser); +} + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + diff --git a/boost/spirit/home/classic/tree/ast_fwd.hpp b/boost/spirit/home/classic/tree/ast_fwd.hpp new file mode 100644 index 0000000000..71ef91b0f5 --- /dev/null +++ b/boost/spirit/home/classic/tree/ast_fwd.hpp @@ -0,0 +1,42 @@ +/*============================================================================= + Copyright (c) 2006 Tobias Schwinger + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_TREE_AST_FWD_HPP) +#define BOOST_SPIRIT_TREE_AST_FWD_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/nil.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + template < + typename MatchPolicyT, + typename NodeFactoryT, + typename T = nil_t + > + struct ast_tree_policy; + + template < + typename IteratorT, + typename NodeFactoryT = node_val_data_factory<nil_t>, + typename T = nil_t + > + struct ast_match_policy; + + template <typename T> + struct gen_ast_node_parser; + + struct root_node_op; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + diff --git a/boost/spirit/home/classic/tree/common.hpp b/boost/spirit/home/classic/tree/common.hpp new file mode 100644 index 0000000000..f25d4915ef --- /dev/null +++ b/boost/spirit/home/classic/tree/common.hpp @@ -0,0 +1,1588 @@ +/*============================================================================= + Copyright (c) 2001-2003 Daniel Nuffer + Copyright (c) 2001-2007 Hartmut Kaiser + Revised 2007, Copyright (c) Tobias Schwinger + 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_TREE_COMMON_HPP +#define BOOST_SPIRIT_TREE_COMMON_HPP + +#if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES) +#include <vector> +#else +#include <list> +#endif + +#if defined(BOOST_SPIRIT_USE_BOOST_ALLOCATOR_FOR_TREES) +#include <boost/pool/pool_alloc.hpp> +#endif + +#include <algorithm> + +#include <boost/ref.hpp> +#include <boost/call_traits.hpp> +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core.hpp> +#include <boost/detail/iterator.hpp> // for boost::detail::iterator_traits +#include <boost/assert.hpp> + +#if defined(BOOST_SPIRIT_DEBUG) && \ + (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES) +#include <iostream> +#include <boost/spirit/home/classic/debug/debug_node.hpp> +#endif + +#include <boost/spirit/home/classic/tree/common_fwd.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +template <typename T> +void swap(tree_node<T>& a, tree_node<T>& b); + +template <typename T, typename V> +void swap(node_iter_data<T, V>& a, node_iter_data<T, V>& b); + +namespace impl { + template <typename T> + inline void cp_swap(T& t1, T& t2); +} + +template <typename T> +struct tree_node +{ + typedef T parse_node_t; + +#if !defined(BOOST_SPIRIT_USE_BOOST_ALLOCATOR_FOR_TREES) + typedef std::allocator<tree_node<T> > allocator_type; +#elif !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES) + typedef boost::pool_allocator<tree_node<T> > allocator_type; +#else + typedef boost::fast_pool_allocator<tree_node<T> > allocator_type; +#endif + +#if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES) + typedef std::vector<tree_node<T>, allocator_type> children_t; +#else + typedef std::list<tree_node<T>, allocator_type> children_t; +#endif // BOOST_SPIRIT_USE_LIST_FOR_TREES + + typedef typename children_t::iterator tree_iterator; + typedef typename children_t::const_iterator const_tree_iterator; + + T value; + children_t children; + + tree_node() + : value() + , children() + {} + + explicit tree_node(T const& v) + : value(v) + , children() + {} + + tree_node(T const& v, children_t const& c) + : value(v) + , children(c) + {} + + void swap(tree_node<T>& x) + { + impl::cp_swap(value, x.value); + impl::cp_swap(children, x.children); + } + +// Intel V5.0.1 has a problem without this explicit operator= + tree_node &operator= (tree_node const &rhs) + { + tree_node(rhs).swap(*this); + return *this; + } +}; + +#if defined(BOOST_SPIRIT_DEBUG) && \ + (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES) +template <typename T> +inline std::ostream& +operator<<(std::ostream& o, tree_node<T> const& n) +{ + static int depth = 0; + o << "\n"; + for (int i = 0; i <= depth; ++i) + { + o << "\t"; + } + o << "(depth = " << depth++ << " value = " << n.value; + int c = 0; + for (typename tree_node<T>::children_t::const_iterator it = n.children.begin(); + it != n.children.end(); ++it) + { + o << " children[" << c++ << "] = " << *it; + } + o << ")"; + --depth; + return o; +} +#endif + +////////////////////////////////// +template <typename IteratorT, typename ValueT> +struct node_iter_data +{ + typedef IteratorT iterator_t; + typedef IteratorT /*const*/ const_iterator_t; + + node_iter_data() + : first(), last(), is_root_(false), parser_id_(), value_() + {} + + node_iter_data(IteratorT const& _first, IteratorT const& _last) + : first(_first), last(_last), is_root_(false), parser_id_(), value_() + {} + + void swap(node_iter_data& x) + { + impl::cp_swap(first, x.first); + impl::cp_swap(last, x.last); + impl::cp_swap(parser_id_, x.parser_id_); + impl::cp_swap(is_root_, x.is_root_); + impl::cp_swap(value_, x.value_); + } + + IteratorT begin() + { + return first; + } + + IteratorT const& begin() const + { + return first; + } + + IteratorT end() + { + return last; + } + + IteratorT const& end() const + { + return last; + } + + bool is_root() const + { + return is_root_; + } + + void is_root(bool b) + { + is_root_ = b; + } + + parser_id id() const + { + return parser_id_; + } + + void id(parser_id r) + { + parser_id_ = r; + } + + ValueT const& value() const + { + return value_; + } + + void value(ValueT const& v) + { + value_ = v; + } +private: + IteratorT first, last; + bool is_root_; + parser_id parser_id_; + ValueT value_; + +public: +}; + +#if defined(BOOST_SPIRIT_DEBUG) && \ + (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES) +// value is default nil_t, so provide an operator<< for nil_t +inline std::ostream& +operator<<(std::ostream& o, nil_t const&) +{ + return o; +} + +template <typename IteratorT, typename ValueT> +inline std::ostream& +operator<<(std::ostream& o, node_iter_data<IteratorT, ValueT> const& n) +{ + o << "(id = " << n.id() << " text = \""; + typedef typename node_iter_data<IteratorT, ValueT>::const_iterator_t + iterator_t; + for (iterator_t it = n.begin(); it != n.end(); ++it) + impl::token_printer(o, *it); + o << "\" is_root = " << n.is_root() + << /*" value = " << n.value() << */")"; + return o; +} +#endif + +////////////////////////////////// +template <typename IteratorT = char const*, typename ValueT = nil_t> +struct node_val_data +{ + typedef + typename boost::detail::iterator_traits<IteratorT>::value_type + value_type; + +#if !defined(BOOST_SPIRIT_USE_BOOST_ALLOCATOR_FOR_TREES) + typedef std::allocator<value_type> allocator_type; +#elif !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES) + typedef boost::pool_allocator<value_type> allocator_type; +#else + typedef boost::fast_pool_allocator<value_type> allocator_type; +#endif + +#if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES) + typedef std::vector<value_type, allocator_type> container_t; +#else + typedef std::list<value_type, allocator_type> container_t; +#endif + + typedef typename container_t::iterator iterator_t; + typedef typename container_t::const_iterator const_iterator_t; + + node_val_data() + : text(), is_root_(false), parser_id_(), value_() + {} + +#if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) + node_val_data(IteratorT const& _first, IteratorT const& _last) + : text(), is_root_(false), parser_id_(), value_() + { + std::copy(_first, _last, std::inserter(text, text.end())); + } + + // This constructor is for building text out of iterators + template <typename IteratorT2> + node_val_data(IteratorT2 const& _first, IteratorT2 const& _last) + : text(), is_root_(false), parser_id_(), value_() + { + std::copy(_first, _last, std::inserter(text, text.end())); + } +#else + node_val_data(IteratorT const& _first, IteratorT const& _last) + : text(_first, _last), is_root_(false), parser_id_(), value_() + {} + + // This constructor is for building text out of iterators + template <typename IteratorT2> + node_val_data(IteratorT2 const& _first, IteratorT2 const& _last) + : text(_first, _last), is_root_(false), parser_id_(), value_() + {} +#endif + + void swap(node_val_data& x) + { + impl::cp_swap(text, x.text); + impl::cp_swap(is_root_, x.is_root_); + impl::cp_swap(parser_id_, x.parser_id_); + impl::cp_swap(value_, x.value_); + } + + typename container_t::iterator begin() + { + return text.begin(); + } + + typename container_t::const_iterator begin() const + { + return text.begin(); + } + + typename container_t::iterator end() + { + return text.end(); + } + + typename container_t::const_iterator end() const + { + return text.end(); + } + + bool is_root() const + { + return is_root_; + } + + void is_root(bool b) + { + is_root_ = b; + } + + parser_id id() const + { + return parser_id_; + } + + void id(parser_id r) + { + parser_id_ = r; + } + + ValueT const& value() const + { + return value_; + } + + void value(ValueT const& v) + { + value_ = v; + } + +private: + container_t text; + bool is_root_; + parser_id parser_id_; + ValueT value_; +}; + +#if defined(BOOST_SPIRIT_DEBUG) && \ + (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES) +template <typename IteratorT, typename ValueT> +inline std::ostream& +operator<<(std::ostream& o, node_val_data<IteratorT, ValueT> const& n) +{ + o << "(id = " << n.id() << " text = \""; + typedef typename node_val_data<IteratorT, ValueT>::const_iterator_t + iterator_t; + for (iterator_t it = n.begin(); it != n.end(); ++it) + impl::token_printer(o, *it); + o << "\" is_root = " << n.is_root() + << " value = " << n.value() << ")"; + return o; +} +#endif + +template <typename T> +inline void +swap(tree_node<T>& a, tree_node<T>& b) +{ + a.swap(b); +} + +template <typename T, typename V> +inline void +swap(node_iter_data<T, V>& a, node_iter_data<T, V>& b) +{ + a.swap(b); +} + +////////////////////////////////// +template <typename ValueT> +class node_iter_data_factory +{ +public: + // This inner class is so that node_iter_data_factory can simulate + // a template template parameter + template <typename IteratorT> + class factory + { + public: + typedef IteratorT iterator_t; + typedef node_iter_data<iterator_t, ValueT> node_t; + + static node_t create_node(iterator_t const& first, iterator_t const& last, + bool /*is_leaf_node*/) + { + return node_t(first, last); + } + + static node_t empty_node() + { + return node_t(); + } + + // precondition: ContainerT contains a tree_node<node_t>. And all + // iterators in the container point to the same sequence. + template <typename ContainerT> + static node_t group_nodes(ContainerT const& nodes) + { + return node_t(nodes.begin()->value.begin(), + nodes.back().value.end()); + } + }; +}; + +////////////////////////////////// +template <typename ValueT> +class node_val_data_factory +{ +public: + // This inner class is so that node_val_data_factory can simulate + // a template template parameter + template <typename IteratorT> + class factory + { + public: + typedef IteratorT iterator_t; + typedef node_val_data<iterator_t, ValueT> node_t; + + static node_t create_node(iterator_t const& first, iterator_t const& last, + bool is_leaf_node) + { + if (is_leaf_node) + return node_t(first, last); + else + return node_t(); + } + + static node_t empty_node() + { + return node_t(); + } + + template <typename ContainerT> + static node_t group_nodes(ContainerT const& nodes) + { + typename node_t::container_t c; + typename ContainerT::const_iterator i_end = nodes.end(); + // copy all the nodes text into a new one + for (typename ContainerT::const_iterator i = nodes.begin(); + i != i_end; ++i) + { + // See docs: reduced_node_d cannot be used with a + // rule inside the []. + BOOST_ASSERT(i->children.size() == 0); + c.insert(c.end(), i->value.begin(), i->value.end()); + } + return node_t(c.begin(), c.end()); + } + }; +}; + +////////////////////////////////// +template <typename ValueT> +class node_all_val_data_factory +{ +public: + // This inner class is so that node_all_val_data_factory can simulate + // a template template parameter + template <typename IteratorT> + class factory + { + public: + typedef IteratorT iterator_t; + typedef node_val_data<iterator_t, ValueT> node_t; + + static node_t create_node(iterator_t const& first, iterator_t const& last, + bool /*is_leaf_node*/) + { + return node_t(first, last); + } + + static node_t empty_node() + { + return node_t(); + } + + template <typename ContainerT> + static node_t group_nodes(ContainerT const& nodes) + { + typename node_t::container_t c; + typename ContainerT::const_iterator i_end = nodes.end(); + // copy all the nodes text into a new one + for (typename ContainerT::const_iterator i = nodes.begin(); + i != i_end; ++i) + { + BOOST_ASSERT(i->children.size() == 0); + c.insert(c.end(), i->value.begin(), i->value.end()); + } + return node_t(c.begin(), c.end()); + } + }; +}; + +namespace impl { + + /////////////////////////////////////////////////////////////////////////// + // can't call unqualified swap from within classname::swap + // as Koenig lookup rules will find only the classname::swap + // member function not the global declaration, so use cp_swap + // as a forwarding function (JM): +#if __GNUC__ == 2 + using ::std::swap; +#endif + template <typename T> + inline void cp_swap(T& t1, T& t2) + { + using std::swap; + using BOOST_SPIRIT_CLASSIC_NS::swap; + using boost::swap; + swap(t1, t2); + } +} + +////////////////////////////////// +template <typename IteratorT, typename NodeFactoryT, typename T> +class tree_match : public match<T> +{ +public: + + typedef typename NodeFactoryT::template factory<IteratorT> node_factory_t; + typedef typename node_factory_t::node_t parse_node_t; + typedef tree_node<parse_node_t> node_t; + typedef typename node_t::children_t container_t; + typedef typename container_t::iterator tree_iterator; + typedef typename container_t::const_iterator const_tree_iterator; + + typedef T attr_t; + typedef typename boost::call_traits<T>::param_type param_type; + typedef typename boost::call_traits<T>::reference reference; + typedef typename boost::call_traits<T>::const_reference const_reference; + + tree_match() + : match<T>(), trees() + {} + + explicit + tree_match(std::size_t length_) + : match<T>(length_), trees() + {} + + tree_match(std::size_t length_, parse_node_t const& n) + : match<T>(length_), trees() + { + trees.push_back(node_t(n)); + } + + tree_match(std::size_t length_, param_type val, parse_node_t const& n) + : match<T>(length_, val), trees() + { +#if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES) + trees.reserve(10); // this is more or less an arbitrary number... +#endif + trees.push_back(node_t(n)); + } + + // attention, these constructors will change the second parameter! + tree_match(std::size_t length_, container_t& c) + : match<T>(length_), trees() + { + impl::cp_swap(trees, c); + } + + tree_match(std::size_t length_, param_type val, container_t& c) + : match<T>(length_, val), trees() + { + impl::cp_swap(trees, c); + } + + template <typename T2> + tree_match(match<T2> const& other) + : match<T>(other), trees() + {} + + template <typename T2, typename T3, typename T4> + tree_match(tree_match<T2, T3, T4> const& other) + : match<T>(other), trees() + { impl::cp_swap(trees, other.trees); } + + template <typename T2> + tree_match& + operator=(match<T2> const& other) + { + match<T>::operator=(other); + return *this; + } + + template <typename T2, typename T3, typename T4> + tree_match& + operator=(tree_match<T2, T3, T4> const& other) + { + match<T>::operator=(other); + impl::cp_swap(trees, other.trees); + return *this; + } + + tree_match(tree_match const& x) + : match<T>(x), trees() + { + // use auto_ptr like ownership for the trees data member + impl::cp_swap(trees, x.trees); + } + + tree_match& operator=(tree_match const& x) + { + tree_match tmp(x); + this->swap(tmp); + return *this; + } + + void swap(tree_match& x) + { + match<T>::swap(x); + impl::cp_swap(trees, x.trees); + } + + mutable container_t trees; +}; + +#if defined(BOOST_SPIRIT_DEBUG) && \ + (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES) +template <typename IteratorT, typename NodeFactoryT, typename T> +inline std::ostream& +operator<<(std::ostream& o, tree_match<IteratorT, NodeFactoryT, T> const& m) +{ + typedef + typename tree_match<IteratorT, NodeFactoryT, T>::container_t::iterator + iterator; + + o << "(length = " << (int)m.length(); + int c = 0; + for (iterator i = m.trees.begin(); i != m.trees.end(); ++i) + { + o << " trees[" << c++ << "] = " << *i; + } + o << "\n)"; + return o; +} +#endif + +////////////////////////////////// +struct tree_policy +{ + template <typename FunctorT, typename MatchT> + static void apply_op_to_match(FunctorT const& /*op*/, MatchT& /*m*/) + {} + + template <typename MatchT, typename Iterator1T, typename Iterator2T> + static void group_match(MatchT& /*m*/, parser_id const& /*id*/, + Iterator1T const& /*first*/, Iterator2T const& /*last*/) + {} + + template <typename MatchT> + static void concat(MatchT& /*a*/, MatchT const& /*b*/) + {} +}; + +////////////////////////////////// +template < + typename MatchPolicyT, + typename IteratorT, + typename NodeFactoryT, + typename TreePolicyT, + typename T +> +struct common_tree_match_policy : public match_policy +{ + common_tree_match_policy() + { + } + + template <typename PolicyT> + common_tree_match_policy(PolicyT const & policies) + : match_policy((match_policy const &)policies) + { + } + + template <typename U> + struct result { typedef tree_match<IteratorT, NodeFactoryT, U> type; }; + + typedef tree_match<IteratorT, NodeFactoryT, T> match_t; + typedef IteratorT iterator_t; + typedef TreePolicyT tree_policy_t; + typedef NodeFactoryT factory_t; + + static const match_t no_match() { return match_t(); } + static const match_t empty_match() + { return match_t(0, tree_policy_t::empty_node()); } + + template <typename AttrT, typename Iterator1T, typename Iterator2T> + static tree_match<IteratorT, NodeFactoryT, AttrT> create_match( + std::size_t length, + AttrT const& val, + Iterator1T const& first, + Iterator2T const& last) + { +#if defined(BOOST_SPIRIT_DEBUG) && \ + (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES) + + BOOST_SPIRIT_DEBUG_OUT << "\n>>> create_node(begin) <<<\n" + "creating node text: \""; + for (Iterator1T it = first; it != last; ++it) + impl::token_printer(BOOST_SPIRIT_DEBUG_OUT, *it); + BOOST_SPIRIT_DEBUG_OUT << "\"\n"; + BOOST_SPIRIT_DEBUG_OUT << ">>> create_node(end) <<<\n\n"; +#endif + return tree_match<IteratorT, NodeFactoryT, AttrT>(length, val, + tree_policy_t::create_node(length, first, last, true)); + } + + template <typename Match1T, typename Match2T> + static void concat_match(Match1T& a, Match2T const& b) + { +#if defined(BOOST_SPIRIT_DEBUG) && \ + (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES) + + BOOST_SPIRIT_DEBUG_OUT << "\n>>> concat_match(begin) <<<\n"; + BOOST_SPIRIT_DEBUG_OUT << "tree a:\n" << a << "\n"; + BOOST_SPIRIT_DEBUG_OUT << "tree b:\n" << b << "\n"; + BOOST_SPIRIT_DEBUG_OUT << ">>> concat_match(end) <<<\n\n"; +#endif + BOOST_SPIRIT_ASSERT(a && b); + if (a.length() == 0) + { + a = b; + return; + } + else if (b.length() == 0 +#ifdef BOOST_SPIRIT_NO_TREE_NODE_COLLAPSING + && !b.trees.begin()->value.id().to_long() +#endif + ) + { + return; + } + a.concat(b); + tree_policy_t::concat(a, b); + } + + template <typename MatchT, typename IteratorT2> + void + group_match( + MatchT& m, + parser_id const& id, + IteratorT2 const& first, + IteratorT2 const& last) const + { + if (!m) return; + +#if defined(BOOST_SPIRIT_DEBUG) && \ + (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_TREES) + + BOOST_SPIRIT_DEBUG_OUT << "\n>>> group_match(begin) <<<\n" + "new node(" << id << ") \""; + for (IteratorT2 it = first; it != last; ++it) + impl::token_printer(BOOST_SPIRIT_DEBUG_OUT, *it); + BOOST_SPIRIT_DEBUG_OUT << "\"\n"; + BOOST_SPIRIT_DEBUG_OUT << "new child tree (before grouping):\n" << m << "\n"; + + tree_policy_t::group_match(m, id, first, last); + + BOOST_SPIRIT_DEBUG_OUT << "new child tree (after grouping):\n" << m << "\n"; + BOOST_SPIRIT_DEBUG_OUT << ">>> group_match(end) <<<\n\n"; +#else + tree_policy_t::group_match(m, id, first, last); +#endif + } +}; + +////////////////////////////////// +template <typename MatchPolicyT, typename NodeFactoryT> +struct common_tree_tree_policy +{ + typedef typename MatchPolicyT::iterator_t iterator_t; + typedef typename MatchPolicyT::match_t match_t; + typedef typename NodeFactoryT::template factory<iterator_t> factory_t; + typedef typename factory_t::node_t node_t; + + template <typename Iterator1T, typename Iterator2T> + static node_t + create_node(std::size_t /*length*/, Iterator1T const& first, + Iterator2T const& last, bool leaf_node) + { + return factory_t::create_node(first, last, leaf_node); + } + + static node_t + empty_node() + { + return factory_t::empty_node(); + } + + template <typename FunctorT> + static void apply_op_to_match(FunctorT const& op, match_t& m) + { + op(m); + } +}; + +////////////////////////////////// +// directives to modify how the parse tree is generated + +struct no_tree_gen_node_parser_gen; + +template <typename T> +struct no_tree_gen_node_parser +: public unary<T, parser<no_tree_gen_node_parser<T> > > +{ + typedef no_tree_gen_node_parser<T> self_t; + typedef no_tree_gen_node_parser_gen parser_generator_t; + typedef unary_parser_category parser_category_t; + + no_tree_gen_node_parser(T const& a) + : unary<T, parser<no_tree_gen_node_parser<T> > >(a) {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scanner) const + { + typedef typename ScannerT::iteration_policy_t iteration_policy_t; + typedef match_policy match_policy_t; + typedef typename ScannerT::action_policy_t action_policy_t; + typedef scanner_policies< + iteration_policy_t, + match_policy_t, + action_policy_t + > policies_t; + + return this->subject().parse(scanner.change_policies(policies_t(scanner))); + } +}; + +struct no_tree_gen_node_parser_gen +{ + template <typename T> + struct result { + + typedef no_tree_gen_node_parser<T> type; + }; + + template <typename T> + static no_tree_gen_node_parser<T> + generate(parser<T> const& s) + { + return no_tree_gen_node_parser<T>(s.derived()); + } + + template <typename T> + no_tree_gen_node_parser<T> + operator[](parser<T> const& s) const + { + return no_tree_gen_node_parser<T>(s.derived()); + } +}; + +const no_tree_gen_node_parser_gen no_node_d = no_tree_gen_node_parser_gen(); + +////////////////////////////////// + +struct leaf_node_parser_gen; + +template<typename T> +struct leaf_node_parser +: public unary<T, parser<leaf_node_parser<T> > > +{ + typedef leaf_node_parser<T> self_t; + typedef leaf_node_parser_gen parser_generator_t; + typedef unary_parser_category parser_category_t; + + leaf_node_parser(T const& a) + : unary<T, parser<leaf_node_parser<T> > >(a) {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scanner) const + { + typedef scanner_policies< typename ScannerT::iteration_policy_t, + match_policy, typename ScannerT::action_policy_t > policies_t; + + typedef typename ScannerT::iterator_t iterator_t; + typedef typename parser_result<self_t, ScannerT>::type result_t; + typedef typename result_t::node_factory_t factory_t; + + iterator_t from = scanner.first; + result_t hit = impl::contiguous_parser_parse<result_t>(this->subject(), + scanner.change_policies(policies_t(scanner,match_policy(),scanner)), + scanner); + + if (hit) + return result_t(hit.length(), + factory_t::create_node(from, scanner.first, true)); + else + return result_t(hit.length()); + } +}; + +struct leaf_node_parser_gen +{ + template <typename T> + struct result { + + typedef leaf_node_parser<T> type; + }; + + template <typename T> + static leaf_node_parser<T> + generate(parser<T> const& s) + { + return leaf_node_parser<T>(s.derived()); + } + + template <typename T> + leaf_node_parser<T> + operator[](parser<T> const& s) const + { + return leaf_node_parser<T>(s.derived()); + } +}; + +const leaf_node_parser_gen leaf_node_d = leaf_node_parser_gen(); +const leaf_node_parser_gen token_node_d = leaf_node_parser_gen(); + +////////////////////////////////// +namespace impl { + + template <typename MatchPolicyT> + struct tree_policy_selector + { + typedef tree_policy type; + }; + +} // namespace impl + +////////////////////////////////// +template <typename NodeParserT> +struct node_parser_gen; + +template <typename T, typename NodeParserT> +struct node_parser +: public unary<T, parser<node_parser<T, NodeParserT> > > +{ + typedef node_parser<T, NodeParserT> self_t; + typedef node_parser_gen<NodeParserT> parser_generator_t; + typedef unary_parser_category parser_category_t; + + node_parser(T const& a) + : unary<T, parser<node_parser<T, NodeParserT> > >(a) {} + + template <typename ScannerT> + struct result + { + typedef typename parser_result<T, ScannerT>::type type; + }; + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scanner) const + { + typename parser_result<self_t, ScannerT>::type hit = this->subject().parse(scanner); + if (hit) + { + impl::tree_policy_selector<typename ScannerT::match_policy_t>::type::apply_op_to_match(NodeParserT(), hit); + } + return hit; + } +}; + +template <typename NodeParserT> +struct node_parser_gen +{ + template <typename T> + struct result { + + typedef node_parser<T, NodeParserT> type; + }; + + template <typename T> + static node_parser<T, NodeParserT> + generate(parser<T> const& s) + { + return node_parser<T, NodeParserT>(s.derived()); + } + + template <typename T> + node_parser<T, NodeParserT> + operator[](parser<T> const& s) const + { + return node_parser<T, NodeParserT>(s.derived()); + } +}; +////////////////////////////////// +struct reduced_node_op +{ + template <typename MatchT> + void operator()(MatchT& m) const + { + if (m.trees.size() == 1) + { + m.trees.begin()->children.clear(); + } + else if (m.trees.size() > 1) + { + typedef typename MatchT::node_factory_t node_factory_t; + m = MatchT(m.length(), node_factory_t::group_nodes(m.trees)); + } + } +}; + +const node_parser_gen<reduced_node_op> reduced_node_d = + node_parser_gen<reduced_node_op>(); + + +struct discard_node_op +{ + template <typename MatchT> + void operator()(MatchT& m) const + { + m.trees.clear(); + } +}; + +const node_parser_gen<discard_node_op> discard_node_d = + node_parser_gen<discard_node_op>(); + +struct infix_node_op +{ + template <typename MatchT> + void operator()(MatchT& m) const + { + typedef typename MatchT::container_t container_t; + typedef typename MatchT::container_t::iterator iter_t; + typedef typename MatchT::container_t::value_type value_t; + + using std::swap; + using boost::swap; + using BOOST_SPIRIT_CLASSIC_NS::swap; + + // copying the tree nodes is expensive, since it may copy a whole + // tree. swapping them is cheap, so swap the nodes we want into + // a new container of children. + container_t new_children; + std::size_t length = 0; + std::size_t tree_size = m.trees.size(); + + // the infix_node_d[] make no sense for nodes with no subnodes + BOOST_SPIRIT_ASSERT(tree_size >= 1); + + bool keep = true; +#if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES) + new_children.reserve((tree_size+1)/2); +#endif + iter_t i_end = m.trees.end(); + for (iter_t i = m.trees.begin(); i != i_end; ++i) + { + if (keep) { + // adjust the length + length += std::distance((*i).value.begin(), (*i).value.end()); + + // move the child node + new_children.push_back(value_t()); + swap(new_children.back(), *i); + keep = false; + } + else { + // ignore this child node + keep = true; + } + } + + m = MatchT(length, new_children); + } +}; + +const node_parser_gen<infix_node_op> infix_node_d = + node_parser_gen<infix_node_op>(); + +struct discard_first_node_op +{ + template <typename MatchT> + void operator()(MatchT& m) const + { + typedef typename MatchT::container_t container_t; + typedef typename MatchT::container_t::iterator iter_t; + typedef typename MatchT::container_t::value_type value_t; + + using std::swap; + using boost::swap; + using BOOST_SPIRIT_CLASSIC_NS::swap; + + // copying the tree nodes is expensive, since it may copy a whole + // tree. swapping them is cheap, so swap the nodes we want into + // a new container of children, instead of saying + // m.trees.erase(m.trees.begin()) because, on a container_t that will + // cause all the nodes afterwards to be copied into the previous + // position. + container_t new_children; + std::size_t length = 0; + std::size_t tree_size = m.trees.size(); + + // the discard_first_node_d[] make no sense for nodes with no subnodes + BOOST_SPIRIT_ASSERT(tree_size >= 1); + + if (tree_size > 1) { +#if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES) + new_children.reserve(tree_size - 1); +#endif + iter_t i = m.trees.begin(), i_end = m.trees.end(); + for (++i; i != i_end; ++i) + { + // adjust the length + length += std::distance((*i).value.begin(), (*i).value.end()); + + // move the child node + new_children.push_back(value_t()); + swap(new_children.back(), *i); + } + } + else { + // if there was a tree and now there isn't any, insert an empty node + iter_t i = m.trees.begin(); + + // This isn't entirely correct, since the empty node will reference + // the end of the discarded node, but I currently don't see any way to + // get at the begin of the node following this subnode. + // This should be safe anyway because the it shouldn't get dereferenced + // under any circumstances. + typedef typename value_t::parse_node_t::iterator_t iterator_type; + iterator_type it = (*i).value.end(); + + new_children.push_back( + value_t(typename value_t::parse_node_t(it, it))); + } + + m = MatchT(length, new_children); + } +}; + +const node_parser_gen<discard_first_node_op> discard_first_node_d = + node_parser_gen<discard_first_node_op>(); + +struct discard_last_node_op +{ + template <typename MatchT> + void operator()(MatchT& m) const + { + typedef typename MatchT::container_t container_t; + typedef typename MatchT::container_t::iterator iter_t; + typedef typename MatchT::container_t::value_type value_t; + + using std::swap; + using boost::swap; + using BOOST_SPIRIT_CLASSIC_NS::swap; + + // copying the tree nodes is expensive, since it may copy a whole + // tree. swapping them is cheap, so swap the nodes we want into + // a new container of children, instead of saying + // m.trees.erase(m.trees.begin()) because, on a container_t that will + // cause all the nodes afterwards to be copied into the previous + // position. + container_t new_children; + std::size_t length = 0; + std::size_t tree_size = m.trees.size(); + + // the discard_last_node_d[] make no sense for nodes with no subnodes + BOOST_SPIRIT_ASSERT(tree_size >= 1); + + if (tree_size > 1) { + m.trees.pop_back(); +#if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES) + new_children.reserve(tree_size - 1); +#endif + iter_t i_end = m.trees.end(); + for (iter_t i = m.trees.begin(); i != i_end; ++i) + { + // adjust the length + length += std::distance((*i).value.begin(), (*i).value.end()); + + // move the child node + new_children.push_back(value_t()); + swap(new_children.back(), *i); + } + } + else { + // if there was a tree and now there isn't any, insert an empty node + iter_t i = m.trees.begin(); + + typedef typename value_t::parse_node_t::iterator_t iterator_type; + iterator_type it = (*i).value.begin(); + + new_children.push_back( + value_t(typename value_t::parse_node_t(it, it))); + } + + m = MatchT(length, new_children); + } +}; + +const node_parser_gen<discard_last_node_op> discard_last_node_d = + node_parser_gen<discard_last_node_op>(); + +struct inner_node_op +{ + template <typename MatchT> + void operator()(MatchT& m) const + { + typedef typename MatchT::container_t container_t; + typedef typename MatchT::container_t::iterator iter_t; + typedef typename MatchT::container_t::value_type value_t; + + using std::swap; + using boost::swap; + using BOOST_SPIRIT_CLASSIC_NS::swap; + + // copying the tree nodes is expensive, since it may copy a whole + // tree. swapping them is cheap, so swap the nodes we want into + // a new container of children, instead of saying + // m.trees.erase(m.trees.begin()) because, on a container_t that will + // cause all the nodes afterwards to be copied into the previous + // position. + container_t new_children; + std::size_t length = 0; + std::size_t tree_size = m.trees.size(); + + // the inner_node_d[] make no sense for nodes with less then 2 subnodes + BOOST_SPIRIT_ASSERT(tree_size >= 2); + + if (tree_size > 2) { + m.trees.pop_back(); // erase the last element +#if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES) + new_children.reserve(tree_size - 1); +#endif + iter_t i = m.trees.begin(); // skip over the first element + iter_t i_end = m.trees.end(); + for (++i; i != i_end; ++i) + { + // adjust the length + length += std::distance((*i).value.begin(), (*i).value.end()); + + // move the child node + new_children.push_back(value_t()); + swap(new_children.back(), *i); + } + } + else { + // if there was a tree and now there isn't any, insert an empty node + iter_t i = m.trees.begin(); // skip over the first element + + typedef typename value_t::parse_node_t::iterator_t iterator_type; + iterator_type it = (*++i).value.begin(); + + new_children.push_back( + value_t(typename value_t::parse_node_t(it, it))); + } + + m = MatchT(length, new_children); + } +}; + +const node_parser_gen<inner_node_op> inner_node_d = + node_parser_gen<inner_node_op>(); + + +////////////////////////////////// +// action_directive_parser and action_directive_parser_gen +// are meant to be used as a template to create directives that +// generate action classes. For example access_match and +// access_node. The ActionParserT template parameter must be +// a class that has an innter class called action that is templated +// on the parser type and the action type. +template <typename ActionParserT> +struct action_directive_parser_gen; + +template <typename T, typename ActionParserT> +struct action_directive_parser +: public unary<T, parser<action_directive_parser<T, ActionParserT> > > +{ + typedef action_directive_parser<T, ActionParserT> self_t; + typedef action_directive_parser_gen<ActionParserT> parser_generator_t; + typedef unary_parser_category parser_category_t; + + action_directive_parser(T const& a) + : unary<T, parser<action_directive_parser<T, ActionParserT> > >(a) {} + + template <typename ScannerT> + struct result + { + typedef typename parser_result<T, ScannerT>::type type; + }; + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scanner) const + { + return this->subject().parse(scanner); + } + + template <typename ActionT> + typename ActionParserT::template action<action_directive_parser<T, ActionParserT>, ActionT> + operator[](ActionT const& actor) const + { + typedef typename + ActionParserT::template action<action_directive_parser, ActionT> + action_t; + return action_t(*this, actor); + } +}; + +////////////////////////////////// +template <typename ActionParserT> +struct action_directive_parser_gen +{ + template <typename T> + struct result { + + typedef action_directive_parser<T, ActionParserT> type; + }; + + template <typename T> + static action_directive_parser<T, ActionParserT> + generate(parser<T> const& s) + { + return action_directive_parser<T, ActionParserT>(s.derived()); + } + + template <typename T> + action_directive_parser<T, ActionParserT> + operator[](parser<T> const& s) const + { + return action_directive_parser<T, ActionParserT>(s.derived()); + } +}; + +////////////////////////////////// +// Calls the attached action passing it the match from the parser +// and the first and last iterators. +// The inner template class is used to simulate template-template parameters +// (declared in common_fwd.hpp). +template <typename ParserT, typename ActionT> +struct access_match_action::action +: public unary<ParserT, parser<access_match_action::action<ParserT, ActionT> > > +{ + typedef action_parser_category parser_category; + typedef action<ParserT, ActionT> self_t; + + template <typename ScannerT> + struct result + { + typedef typename parser_result<ParserT, ScannerT>::type type; + }; + + action( ParserT const& subject, + ActionT const& actor_); + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scanner) const; + + ActionT const &predicate() const; + + private: + ActionT actor; +}; + +////////////////////////////////// +template <typename ParserT, typename ActionT> +access_match_action::action<ParserT, ActionT>::action( + ParserT const& subject, + ActionT const& actor_) +: unary<ParserT, parser<access_match_action::action<ParserT, ActionT> > >(subject) +, actor(actor_) +{} + +////////////////////////////////// +template <typename ParserT, typename ActionT> +template <typename ScannerT> +typename parser_result<access_match_action::action<ParserT, ActionT>, ScannerT>::type +access_match_action::action<ParserT, ActionT>:: +parse(ScannerT const& scan) const +{ + typedef typename ScannerT::iterator_t iterator_t; + typedef typename parser_result<self_t, ScannerT>::type result_t; + if (!scan.at_end()) + { + iterator_t save = scan.first; + result_t hit = this->subject().parse(scan); + actor(hit, save, scan.first); + return hit; + } + return scan.no_match(); +} + +////////////////////////////////// +template <typename ParserT, typename ActionT> +ActionT const &access_match_action::action<ParserT, ActionT>::predicate() const +{ + return actor; +} + +////////////////////////////////// +const action_directive_parser_gen<access_match_action> access_match_d + = action_directive_parser_gen<access_match_action>(); + + + +////////////////////////////////// +// Calls the attached action passing it the node from the parser +// and the first and last iterators +// The inner template class is used to simulate template-template parameters +// (declared in common_fwd.hpp). +template <typename ParserT, typename ActionT> +struct access_node_action::action +: public unary<ParserT, parser<access_node_action::action<ParserT, ActionT> > > +{ + typedef action_parser_category parser_category; + typedef action<ParserT, ActionT> self_t; + + template <typename ScannerT> + struct result + { + typedef typename parser_result<ParserT, ScannerT>::type type; + }; + + action( ParserT const& subject, + ActionT const& actor_); + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scanner) const; + + ActionT const &predicate() const; + + private: + ActionT actor; +}; + +////////////////////////////////// +template <typename ParserT, typename ActionT> +access_node_action::action<ParserT, ActionT>::action( + ParserT const& subject, + ActionT const& actor_) +: unary<ParserT, parser<access_node_action::action<ParserT, ActionT> > >(subject) +, actor(actor_) +{} + +////////////////////////////////// +template <typename ParserT, typename ActionT> +template <typename ScannerT> +typename parser_result<access_node_action::action<ParserT, ActionT>, ScannerT>::type +access_node_action::action<ParserT, ActionT>:: +parse(ScannerT const& scan) const +{ + typedef typename ScannerT::iterator_t iterator_t; + typedef typename parser_result<self_t, ScannerT>::type result_t; + if (!scan.at_end()) + { + iterator_t save = scan.first; + result_t hit = this->subject().parse(scan); + if (hit && hit.trees.size() > 0) + actor(*hit.trees.begin(), save, scan.first); + return hit; + } + return scan.no_match(); +} + +////////////////////////////////// +template <typename ParserT, typename ActionT> +ActionT const &access_node_action::action<ParserT, ActionT>::predicate() const +{ + return actor; +} + +////////////////////////////////// +const action_directive_parser_gen<access_node_action> access_node_d + = action_directive_parser_gen<access_node_action>(); + + + +////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// +// tree_parse_info +// +// Results returned by the tree parse functions: +// +// stop: points to the final parse position (i.e parsing +// processed the input up to this point). +// +// match: true if parsing is successful. This may be full: +// the parser consumed all the input, or partial: +// the parser consumed only a portion of the input. +// +// full: true when we have a full match (i.e the parser +// consumed all the input. +// +// length: The number of characters consumed by the parser. +// This is valid only if we have a successful match +// (either partial or full). A negative value means +// that the match is unsucessful. +// +// trees: Contains the root node(s) of the tree. +// +/////////////////////////////////////////////////////////////////////////////// +template < + typename IteratorT, + typename NodeFactoryT, + typename T +> +struct tree_parse_info +{ + IteratorT stop; + bool match; + bool full; + std::size_t length; + typename tree_match<IteratorT, NodeFactoryT, T>::container_t trees; + + tree_parse_info() + : stop() + , match(false) + , full(false) + , length(0) + , trees() + {} + + template <typename IteratorT2> + tree_parse_info(tree_parse_info<IteratorT2> const& pi) + : stop(pi.stop) + , match(pi.match) + , full(pi.full) + , length(pi.length) + , trees() + { + using std::swap; + using boost::swap; + using BOOST_SPIRIT_CLASSIC_NS::swap; + + // use auto_ptr like ownership for the trees data member + swap(trees, pi.trees); + } + + tree_parse_info( + IteratorT stop_, + bool match_, + bool full_, + std::size_t length_, + typename tree_match<IteratorT, NodeFactoryT, T>::container_t trees_) + : stop(stop_) + , match(match_) + , full(full_) + , length(length_) + , trees() + { + using std::swap; + using boost::swap; + using BOOST_SPIRIT_CLASSIC_NS::swap; + + // use auto_ptr like ownership for the trees data member + swap(trees, trees_); + } +}; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + diff --git a/boost/spirit/home/classic/tree/common_fwd.hpp b/boost/spirit/home/classic/tree/common_fwd.hpp new file mode 100644 index 0000000000..1388e53b7f --- /dev/null +++ b/boost/spirit/home/classic/tree/common_fwd.hpp @@ -0,0 +1,96 @@ +/*============================================================================= + Copyright (c) 2006 Tobias Schwinger + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_TREE_COMMON_FWD_HPP) +#define BOOST_SPIRIT_TREE_COMMON_FWD_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/nil.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + template <typename T> + struct tree_node; + + template <typename IteratorT = char const*, typename ValueT = nil_t> + struct node_iter_data; + + template <typename ValueT = nil_t> + class node_iter_data_factory; + + template <typename ValueT = nil_t> + class node_val_data_factory; + + template <typename ValueT = nil_t> + class node_all_val_data_factory; + + template < + typename IteratorT, + typename NodeFactoryT = node_val_data_factory<nil_t>, + typename T = nil_t + > + class tree_match; + + struct tree_policy; + + template < + typename MatchPolicyT, + typename IteratorT, + typename NodeFactoryT, + typename TreePolicyT, + typename T = nil_t + > + struct common_tree_match_policy; + + template <typename MatchPolicyT, typename NodeFactoryT> + struct common_tree_tree_policy; + + template <typename T> + struct no_tree_gen_node_parser; + + template <typename T> + struct leaf_node_parser; + + template <typename T, typename NodeParserT> + struct node_parser; + + struct discard_node_op; + struct reduced_node_op; + struct infix_node_op; + struct discard_first_node_op; + struct discard_last_node_op; + struct inner_node_op; + + template <typename T, typename ActionParserT> + struct action_directive_parser; + + struct access_match_action + { + template <typename ParserT, typename ActionT> + struct action; + }; + + struct access_node_action + { + template <typename ParserT, typename ActionT> + struct action; + }; + + template < + typename IteratorT = char const *, + typename NodeFactoryT = node_val_data_factory<nil_t>, + typename T = nil_t + > + struct tree_parse_info; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif diff --git a/boost/spirit/home/classic/tree/impl/parse_tree_utils.ipp b/boost/spirit/home/classic/tree/impl/parse_tree_utils.ipp new file mode 100644 index 0000000000..02725208eb --- /dev/null +++ b/boost/spirit/home/classic/tree/impl/parse_tree_utils.ipp @@ -0,0 +1,135 @@ +/*============================================================================= + Copyright (c) 2001-2007 Hartmut Kaiser + 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) +=============================================================================*/ + +#if !defined(PARSE_TREE_UTILS_IPP) +#define PARSE_TREE_UTILS_IPP + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { +namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// +// Returnes the first leaf node of the given parsetree. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename T> +inline tree_node<T> const & +get_first_leaf (tree_node<T> const &node) +{ + if (node.children.size() > 0) + return get_first_leaf(*node.children.begin()); + return node; +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Find a specified node through recursive search. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename T> +inline bool +find_node (tree_node<T> const &node, parser_id node_to_search, + tree_node<T> const **found_node) +{ + if (node.value.id() == node_to_search) { + *found_node = &node; + return true; + } + if (node.children.size() > 0) { + typedef typename tree_node<T>::const_tree_iterator const_tree_iterator; + + const_tree_iterator end = node.children.end(); + for (const_tree_iterator it = node.children.begin(); it != end; ++it) + { + if (find_node (*it, node_to_search, found_node)) + return true; + } + } + return false; // not found here +} + +/////////////////////////////////////////////////////////////////////////////// +// +// The functions 'get_node_range' return a pair of iterators pointing at the +// range, which containes the elements of a specified node. +// +/////////////////////////////////////////////////////////////////////////////// +namespace impl { + +template <typename T> +inline bool +get_node_range (typename tree_node<T>::const_tree_iterator const &start, + parser_id node_to_search, + std::pair<typename tree_node<T>::const_tree_iterator, + typename tree_node<T>::const_tree_iterator> &nodes) +{ +// look at this node first +tree_node<T> const &node = *start; + + if (node.value.id() == node_to_search) { + if (node.children.size() > 0) { + // full subrange + nodes.first = node.children.begin(); + nodes.second = node.children.end(); + } + else { + // only this node + nodes.first = start; + nodes.second = start; + std::advance(nodes.second, 1); + } + return true; + } + +// look at subnodes now + if (node.children.size() > 0) { + typedef typename tree_node<T>::const_tree_iterator const_tree_iterator; + + const_tree_iterator end = node.children.end(); + for (const_tree_iterator it = node.children.begin(); it != end; ++it) + { + if (impl::get_node_range<T>(it, node_to_search, nodes)) + return true; + } + } + return false; +} + +} // end of namespace impl + +template <typename T> +inline bool +get_node_range (tree_node<T> const &node, parser_id node_to_search, + std::pair<typename tree_node<T>::const_tree_iterator, + typename tree_node<T>::const_tree_iterator> &nodes) +{ + if (node.children.size() > 0) { + typedef typename tree_node<T>::const_tree_iterator const_tree_iterator; + + const_tree_iterator end = node.children.end(); + for (const_tree_iterator it = node.children.begin(); it != end; ++it) + { + if (impl::get_node_range<T>(it, node_to_search, nodes)) + return true; + } + } + return false; +} + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +} // namespace spirit +} // namespace boost + +#endif // !defined(PARSE_TREE_UTILS_IPP) diff --git a/boost/spirit/home/classic/tree/impl/tree_to_xml.ipp b/boost/spirit/home/classic/tree/impl/tree_to_xml.ipp new file mode 100644 index 0000000000..2f0da8bf44 --- /dev/null +++ b/boost/spirit/home/classic/tree/impl/tree_to_xml.ipp @@ -0,0 +1,526 @@ +/*============================================================================= + Copyright (c) 2001-2008 Hartmut Kaiser + 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) +=============================================================================*/ + +#if !defined(TREE_TO_XML_IPP) +#define TREE_TO_XML_IPP + +#include <cstdio> +#include <cstdarg> +#include <locale> +#include <string> +#include <cstring> + +#include <map> +#include <iostream> +#include <boost/config.hpp> +#include <boost/assert.hpp> + +#ifdef BOOST_NO_STRINGSTREAM +#include <strstream> +#define BOOST_SPIRIT_OSSTREAM std::ostrstream +inline +std::string BOOST_SPIRIT_GETSTRING(std::ostrstream& ss) +{ + ss << std::ends; + std::string rval = ss.str(); + ss.freeze(false); + return rval; +} +#else +#include <sstream> +#define BOOST_SPIRIT_GETSTRING(ss) ss.str() +#define BOOST_SPIRIT_OSSTREAM std::basic_ostringstream<CharT> +#endif + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +namespace impl { + + /////////////////////////////////////////////////////////////////////////// + template <typename CharT> + struct string_lit; + + template <> + struct string_lit<char> + { + static char get(char c) { return c; } + static std::string get(char const* str = "") { return str; } + }; + + template <> + struct string_lit<wchar_t> + { + static wchar_t get(char c) + { + typedef std::ctype<wchar_t> ctype_t; + return std::use_facet<ctype_t>(std::locale()).widen(c); + } + static std::basic_string<wchar_t> get(char const* source = "") + { + using namespace std; // some systems have size_t in ns std + size_t len = strlen(source); + std::auto_ptr<wchar_t> result (new wchar_t[len+1]); + result.get()[len] = '\0'; + + // working with wide character streams is supported only if the + // platform provides the std::ctype<wchar_t> facet + BOOST_ASSERT(std::has_facet<std::ctype<wchar_t> >(std::locale())); + + std::use_facet<std::ctype<wchar_t> >(std::locale()) + .widen(source, source + len, result.get()); + return result.get(); + } + }; +} + +// xml formatting helper classes +namespace xml { + + template <typename CharT> + inline void + encode (std::basic_string<CharT> &str, char s, char const *r, int len) + { + typedef typename std::basic_string<CharT>::size_type size_type; + + size_type pos = 0; + while ((pos = str.find_first_of (impl::string_lit<CharT>::get(s), pos)) != + size_type(std::basic_string<CharT>::npos)) + { + str.replace (pos, 1, impl::string_lit<CharT>::get(r)); + pos += len; + } + } + + template <typename CharT> + inline std::basic_string<CharT> + encode (std::basic_string<CharT> str) + { + encode(str, '&', "&", 3); + encode(str, '<', "<", 2); + encode(str, '>', ">", 2); + encode(str, '\r', "\\r", 1); + encode(str, '\n', "\\n", 1); + return str; + } + + template <typename CharT> + inline std::basic_string<CharT> + encode (CharT const *text) + { + return encode (std::basic_string<CharT>(text)); + } + + // format a xml attribute + template <typename CharT> + struct attribute + { + attribute() + { + } + + attribute (std::basic_string<CharT> const& key_, + std::basic_string<CharT> const& value_) + : key (key_), value(value_) + { + } + + bool has_value() + { + return value.size() > 0; + } + + std::basic_string<CharT> key; + std::basic_string<CharT> value; + }; + + template <typename CharT> + inline std::basic_ostream<CharT>& + operator<< (std::basic_ostream<CharT> &ostrm, attribute<CharT> const &attr) + { + if (0 == attr.key.size()) + return ostrm; + ostrm << impl::string_lit<CharT>::get(" ") << encode(attr.key) + << impl::string_lit<CharT>::get("=\"") << encode(attr.value) + << impl::string_lit<CharT>::get("\""); + return ostrm; + } + + // output a xml element (base class, not used directly) + template <typename CharT> + class element + { + protected: + element(std::basic_ostream<CharT> &ostrm_, bool incr_indent_ = true) + : ostrm(ostrm_), incr_indent(incr_indent_) + { + if (incr_indent) ++get_indent(); + } + ~element() + { + if (incr_indent) --get_indent(); + } + + public: + void output_space () + { + for (int i = 0; i < get_indent(); i++) + ostrm << impl::string_lit<CharT>::get(" "); + } + + protected: + int &get_indent() + { + static int indent; + + return indent; + } + + std::basic_ostream<CharT> &ostrm; + bool incr_indent; + }; + + // a xml node + template <typename CharT> + class node : public element<CharT> + { + public: + node (std::basic_ostream<CharT> &ostrm_, + std::basic_string<CharT> const& tag_, attribute<CharT> &attr) + : element<CharT>(ostrm_), tag(tag_) + { + this->output_space(); + this->ostrm + << impl::string_lit<CharT>::get("<") << tag_ << attr + << impl::string_lit<CharT>::get(">\n"); + } + node (std::basic_ostream<CharT> &ostrm_, + std::basic_string<CharT> const& tag_) + : element<CharT>(ostrm_), tag(tag_) + { + this->output_space(); + this->ostrm + << impl::string_lit<CharT>::get("<") << tag_ + << impl::string_lit<CharT>::get(">\n"); + } + ~node() + { + this->output_space(); + this->ostrm + << impl::string_lit<CharT>::get("</") << tag + << impl::string_lit<CharT>::get(">\n"); + } + + private: + std::basic_string<CharT> tag; + }; + + template <typename CharT> + class text : public element<CharT> + { + public: + text (std::basic_ostream<CharT> &ostrm_, + std::basic_string<CharT> const& tag, + std::basic_string<CharT> const& textlit) + : element<CharT>(ostrm_) + { + this->output_space(); + this->ostrm + << impl::string_lit<CharT>::get("<") << tag + << impl::string_lit<CharT>::get(">") << encode(textlit) + << impl::string_lit<CharT>::get("</") << tag + << impl::string_lit<CharT>::get(">\n"); + } + + text (std::basic_ostream<CharT> &ostrm_, + std::basic_string<CharT> const& tag, + std::basic_string<CharT> const& textlit, + attribute<CharT> &attr) + : element<CharT>(ostrm_) + { + this->output_space(); + this->ostrm + << impl::string_lit<CharT>::get("<") << tag << attr + << impl::string_lit<CharT>::get(">") << encode(textlit) + << impl::string_lit<CharT>::get("</") << tag + << impl::string_lit<CharT>::get(">\n"); + } + + text (std::basic_ostream<CharT> &ostrm_, + std::basic_string<CharT> const& tag, + std::basic_string<CharT> const& textlit, + attribute<CharT> &attr1, attribute<CharT> &attr2) + : element<CharT>(ostrm_) + { + this->output_space(); + this->ostrm + << impl::string_lit<CharT>::get("<") << tag << attr1 << attr2 + << impl::string_lit<CharT>::get(">") << encode(textlit) + << impl::string_lit<CharT>::get("</") << tag + << impl::string_lit<CharT>::get(">\n"); + } + }; + + // a xml comment + template <typename CharT> + class comment : public element<CharT> + { + public: + comment (std::basic_ostream<CharT> &ostrm_, + std::basic_string<CharT> const& commentlit) + : element<CharT>(ostrm_, false) + { + if ('\0' != commentlit[0]) + { + this->output_space(); + this->ostrm << impl::string_lit<CharT>::get("<!-- ") + << encode(commentlit) + << impl::string_lit<CharT>::get(" -->\n"); + } + } + }; + + // a xml document + template <typename CharT> + class document : public element<CharT> + { + public: + document (std::basic_ostream<CharT> &ostrm_) + : element<CharT>(ostrm_) + { + this->get_indent() = -1; + this->ostrm << impl::string_lit<CharT>::get( + "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); + } + + document (std::basic_ostream<CharT> &ostrm_, + std::basic_string<CharT> const& mainnode, + std::basic_string<CharT> const& dtd) + : element<CharT>(ostrm_) + { + this->get_indent() = -1; + this->ostrm << impl::string_lit<CharT>::get( + "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); + + this->output_space(); + this->ostrm << impl::string_lit<CharT>::get("<!DOCTYPE ") << mainnode + << impl::string_lit<CharT>::get(" SYSTEM \"") << dtd + << impl::string_lit<CharT>::get("\">\n"); + } + ~document() + { + BOOST_SPIRIT_ASSERT(-1 == this->get_indent()); + } + }; + +} // end of namespace xml + +namespace impl { + + /////////////////////////////////////////////////////////////////////////// + // look up the rule name from the given parser_id + template <typename AssocContainerT> + inline typename AssocContainerT::value_type::second_type + get_rulename (AssocContainerT const &id_to_name_map, + BOOST_SPIRIT_CLASSIC_NS::parser_id const &id) + { + typename AssocContainerT::const_iterator it = id_to_name_map.find(id); + if (it != id_to_name_map.end()) + return (*it).second; + typedef typename AssocContainerT::value_type::second_type second_t; + return second_t(); + } + + // dump a parse tree as xml + template < + typename CharT, typename IteratorT, typename GetIdT, typename GetValueT + > + inline void + token_to_xml (std::basic_ostream<CharT> &ostrm, IteratorT const &it, + bool is_root, GetIdT const &get_token_id, GetValueT const &get_token_value) + { + BOOST_SPIRIT_OSSTREAM stream; + + stream << get_token_id(*it) << std::ends; + xml::attribute<CharT> token_id ( + impl::string_lit<CharT>::get("id"), + BOOST_SPIRIT_GETSTRING(stream).c_str()); + xml::attribute<CharT> is_root_attr ( + impl::string_lit<CharT>::get("is_root"), + impl::string_lit<CharT>::get(is_root ? "1" : "")); + xml::attribute<CharT> nil; + xml::text<CharT>(ostrm, + impl::string_lit<CharT>::get("token"), + get_token_value(*it).c_str(), + token_id, + is_root_attr.has_value() ? is_root_attr : nil); + } + + template < + typename CharT, typename TreeNodeT, typename AssocContainerT, + typename GetIdT, typename GetValueT + > + inline void + tree_node_to_xml (std::basic_ostream<CharT> &ostrm, TreeNodeT const &node, + AssocContainerT const& id_to_name_map, GetIdT const &get_token_id, + GetValueT const &get_token_value) + { + typedef typename TreeNodeT::const_iterator node_iter_t; + typedef + typename TreeNodeT::value_type::parse_node_t::const_iterator_t + value_iter_t; + + xml::attribute<CharT> nil; + node_iter_t end = node.end(); + for (node_iter_t it = node.begin(); it != end; ++it) + { + // output a node + xml::attribute<CharT> id ( + impl::string_lit<CharT>::get("rule"), + get_rulename(id_to_name_map, (*it).value.id()).c_str()); + xml::node<CharT> currnode (ostrm, + impl::string_lit<CharT>::get("parsenode"), + (*it).value.id() != 0 && id.has_value() ? id : nil); + + // first dump the value + std::size_t cnt = std::distance((*it).value.begin(), (*it).value.end()); + + if (1 == cnt) + { + token_to_xml (ostrm, (*it).value.begin(), + (*it).value.is_root(), get_token_id, get_token_value); + } + else if (cnt > 1) + { + xml::node<CharT> value (ostrm, + impl::string_lit<CharT>::get("value")); + bool is_root = (*it).value.is_root(); + + value_iter_t val_end = (*it).value.end(); + for (value_iter_t val_it = (*it).value.begin(); + val_it != val_end; ++val_it) + { + token_to_xml (ostrm, val_it, is_root, get_token_id, + get_token_value); + } + } + tree_node_to_xml(ostrm, (*it).children, id_to_name_map, + get_token_id, get_token_value); // dump all subnodes + } + } + + template <typename CharT, typename TreeNodeT, typename AssocContainerT> + inline void + tree_node_to_xml (std::basic_ostream<CharT> &ostrm, TreeNodeT const &node, + AssocContainerT const& id_to_name_map) + { + typedef typename TreeNodeT::const_iterator node_iter_t; + + xml::attribute<CharT> nil; + node_iter_t end = node.end(); + for (node_iter_t it = node.begin(); it != end; ++it) + { + // output a node + xml::attribute<CharT> id ( + impl::string_lit<CharT>::get("rule"), + get_rulename(id_to_name_map, (*it).value.id()).c_str()); + xml::node<CharT> currnode (ostrm, + impl::string_lit<CharT>::get("parsenode"), + (*it).value.id() != parser_id() && id.has_value() ? id : nil); + + // first dump the value + if ((*it).value.begin() != (*it).value.end()) + { + std::basic_string<CharT> tokens ((*it).value.begin(), (*it).value.end()); + + if (tokens.size() > 0) + { + // output all subtokens as one string (for better readability) + xml::attribute<CharT> is_root ( + impl::string_lit<CharT>::get("is_root"), + impl::string_lit<CharT>::get((*it).value.is_root() ? "1" : "")); + xml::text<CharT>(ostrm, + impl::string_lit<CharT>::get("value"), tokens.c_str(), + is_root.has_value() ? is_root : nil); + } + + } + // dump all subnodes + tree_node_to_xml(ostrm, (*it).children, id_to_name_map); + } + } + +} // namespace impl + +/////////////////////////////////////////////////////////////////////////////// +// dump a parse tree as a xml stream (generic variant) +template < + typename CharT, typename TreeNodeT, typename AssocContainerT, + typename GetIdT, typename GetValueT +> +inline void +basic_tree_to_xml (std::basic_ostream<CharT> &ostrm, TreeNodeT const &tree, +std::basic_string<CharT> const &input_line, AssocContainerT const& id_to_name, + GetIdT const &get_token_id, GetValueT const &get_token_value) +{ + // generate xml dump + xml::document<CharT> doc (ostrm, + impl::string_lit<CharT>::get("parsetree"), + impl::string_lit<CharT>::get("parsetree.dtd")); + xml::comment<CharT> input (ostrm, input_line.c_str()); + xml::attribute<CharT> ver ( + impl::string_lit<CharT>::get("version"), + impl::string_lit<CharT>::get("1.0")); + xml::node<CharT> mainnode (ostrm, + impl::string_lit<CharT>::get("parsetree"), ver); + + impl::tree_node_to_xml (ostrm, tree, id_to_name, get_token_id, + get_token_value); +} + +// dump a parse tree as a xml steam (for character based parsers) +template <typename CharT, typename TreeNodeT, typename AssocContainerT> +inline void +basic_tree_to_xml (std::basic_ostream<CharT> &ostrm, TreeNodeT const &tree, + std::basic_string<CharT> const &input_line, + AssocContainerT const& id_to_name) +{ + // generate xml dump + xml::document<CharT> doc (ostrm, + impl::string_lit<CharT>::get("parsetree"), + impl::string_lit<CharT>::get("parsetree.dtd")); + xml::comment<CharT> input (ostrm, input_line.c_str()); + xml::attribute<CharT> ver ( + impl::string_lit<CharT>::get("version"), + impl::string_lit<CharT>::get("1.0")); + xml::node<CharT> mainnode (ostrm, + impl::string_lit<CharT>::get("parsetree"), ver); + + impl::tree_node_to_xml(ostrm, tree, id_to_name); +} + +template <typename CharT, typename TreeNodeT> +inline void +basic_tree_to_xml (std::basic_ostream<CharT> &ostrm, TreeNodeT const &tree, + std::basic_string<CharT> const &input_line) +{ + return basic_tree_to_xml<CharT>(ostrm, tree, input_line, + std::map<BOOST_SPIRIT_CLASSIC_NS::parser_id, std::basic_string<CharT> >()); +} + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#undef BOOST_SPIRIT_OSSTREAM +#undef BOOST_SPIRIT_GETSTRING + +#endif // !defined(PARSE_TREE_XML_HPP) diff --git a/boost/spirit/home/classic/tree/parse_tree.hpp b/boost/spirit/home/classic/tree/parse_tree.hpp new file mode 100644 index 0000000000..dcca9b3fb4 --- /dev/null +++ b/boost/spirit/home/classic/tree/parse_tree.hpp @@ -0,0 +1,296 @@ +/*============================================================================= + Copyright (c) 2001-2003 Daniel Nuffer + Copyright (c) 2001-2007 Hartmut Kaiser + 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_TREE_PARSE_TREE_HPP +#define BOOST_SPIRIT_TREE_PARSE_TREE_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/tree/common.hpp> +#include <boost/spirit/home/classic/core/scanner/scanner.hpp> + +#include <boost/spirit/home/classic/tree/parse_tree_fwd.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +////////////////////////////////// +// pt_match_policy is simply an id so the correct specialization of tree_policy can be found. +template < + typename IteratorT, + typename NodeFactoryT, + typename T +> +struct pt_match_policy : + public common_tree_match_policy< + pt_match_policy<IteratorT, NodeFactoryT, T>, + IteratorT, + NodeFactoryT, + pt_tree_policy< + pt_match_policy<IteratorT, NodeFactoryT, T>, + NodeFactoryT, + T + >, + T + > +{ + typedef + common_tree_match_policy< + pt_match_policy<IteratorT, NodeFactoryT, T>, + IteratorT, + NodeFactoryT, + pt_tree_policy< + pt_match_policy<IteratorT, NodeFactoryT, T>, + NodeFactoryT, + T + >, + T + > + common_tree_match_policy_; + + pt_match_policy() + { + } + + template <typename PolicyT> + pt_match_policy(PolicyT const & policies) + : common_tree_match_policy_(policies) + { + } +}; + +////////////////////////////////// +template <typename MatchPolicyT, typename NodeFactoryT, typename T> +struct pt_tree_policy : + public common_tree_tree_policy<MatchPolicyT, NodeFactoryT> +{ + typedef typename MatchPolicyT::match_t match_t; + typedef typename MatchPolicyT::iterator_t iterator_t; + + template<typename MatchAT, typename MatchBT> + static void concat(MatchAT& a, MatchBT const& b) + { + typedef typename match_t::attr_t attr_t; + BOOST_SPIRIT_ASSERT(a && b); + + std::copy(b.trees.begin(), b.trees.end(), + std::back_insert_iterator<typename match_t::container_t>(a.trees)); + } + + template <typename MatchT, typename Iterator1T, typename Iterator2T> + static void group_match(MatchT& m, parser_id const& id, + Iterator1T const& first, Iterator2T const& last) + { + if (!m) + return; + + typedef typename NodeFactoryT::template factory<iterator_t> factory_t; + typedef typename tree_match<iterator_t, NodeFactoryT, T>::container_t + container_t; + typedef typename container_t::iterator cont_iterator_t; + + match_t newmatch(m.length(), + factory_t::create_node(first, last, false)); + + std::swap(newmatch.trees.begin()->children, m.trees); + // set this node and all it's unset children's rule_id + newmatch.trees.begin()->value.id(id); + for (cont_iterator_t i = newmatch.trees.begin()->children.begin(); + i != newmatch.trees.begin()->children.end(); + ++i) + { + if (i->value.id() == 0) + i->value.id(id); + } + m = newmatch; + } + + template <typename FunctorT, typename MatchT> + static void apply_op_to_match(FunctorT const& op, MatchT& m) + { + op(m); + } +}; + +namespace impl { + + template <typename IteratorT, typename NodeFactoryT, typename T> + struct tree_policy_selector<pt_match_policy<IteratorT, NodeFactoryT, T> > + { + typedef pt_tree_policy< + pt_match_policy<IteratorT, NodeFactoryT, T>, + NodeFactoryT, + T + > type; + }; + +} // namespace impl + + +////////////////////////////////// +struct gen_pt_node_parser_gen; + +template <typename T> +struct gen_pt_node_parser +: public unary<T, parser<gen_pt_node_parser<T> > > +{ + typedef gen_pt_node_parser<T> self_t; + typedef gen_pt_node_parser_gen parser_generator_t; + typedef unary_parser_category parser_category_t; + + gen_pt_node_parser(T const& a) + : unary<T, parser<gen_pt_node_parser<T> > >(a) {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename ScannerT::iteration_policy_t iteration_policy_t; + typedef typename ScannerT::match_policy_t::iterator_t iterator_t; + typedef typename ScannerT::match_policy_t::factory_t factory_t; + typedef pt_match_policy<iterator_t, factory_t> match_policy_t; + typedef typename ScannerT::action_policy_t action_policy_t; + typedef scanner_policies< + iteration_policy_t, + match_policy_t, + action_policy_t + > policies_t; + + return this->subject().parse(scan.change_policies(policies_t(scan))); + } +}; + +////////////////////////////////// +struct gen_pt_node_parser_gen +{ + template <typename T> + struct result { + + typedef gen_pt_node_parser<T> type; + }; + + template <typename T> + static gen_pt_node_parser<T> + generate(parser<T> const& s) + { + return gen_pt_node_parser<T>(s.derived()); + } + + template <typename T> + gen_pt_node_parser<T> + operator[](parser<T> const& s) const + { + return gen_pt_node_parser<T>(s.derived()); + } +}; + +////////////////////////////////// +const gen_pt_node_parser_gen gen_pt_node_d = gen_pt_node_parser_gen(); + + +/////////////////////////////////////////////////////////////////////////////// +// +// Parse functions for parse trees +// +/////////////////////////////////////////////////////////////////////////////// +template < + typename NodeFactoryT, typename IteratorT, typename ParserT, + typename SkipT +> +inline tree_parse_info<IteratorT, NodeFactoryT> +pt_parse( + IteratorT const& first_, + IteratorT const& last, + parser<ParserT> const& p, + SkipT const& skip, + NodeFactoryT const& /*dummy_*/ = NodeFactoryT()) +{ + typedef skip_parser_iteration_policy<SkipT> iter_policy_t; + typedef pt_match_policy<IteratorT, NodeFactoryT> pt_match_policy_t; + typedef + scanner_policies<iter_policy_t, pt_match_policy_t> + scanner_policies_t; + typedef scanner<IteratorT, scanner_policies_t> scanner_t; + + iter_policy_t iter_policy(skip); + scanner_policies_t policies(iter_policy); + IteratorT first = first_; + scanner_t scan(first, last, policies); + tree_match<IteratorT, NodeFactoryT> hit = p.derived().parse(scan); + return tree_parse_info<IteratorT, NodeFactoryT>( + first, hit, hit && (first == last), hit.length(), hit.trees); +} + +template <typename IteratorT, typename ParserT, typename SkipT> +inline tree_parse_info<IteratorT> +pt_parse( + IteratorT const& first, + IteratorT const& last, + parser<ParserT> const& p, + SkipT const& skip) +{ + typedef node_val_data_factory<nil_t> default_node_factory_t; + return pt_parse(first, last, p, skip, default_node_factory_t()); +} + +////////////////////////////////// +template <typename IteratorT, typename ParserT> +inline tree_parse_info<IteratorT> +pt_parse( + IteratorT const& first_, + IteratorT const& last, + parser<ParserT> const& parser) +{ + typedef pt_match_policy<IteratorT> pt_match_policy_t; + IteratorT first = first_; + scanner< + IteratorT, + scanner_policies<iteration_policy, pt_match_policy_t> + > scan(first, last); + tree_match<IteratorT> hit = parser.derived().parse(scan); + return tree_parse_info<IteratorT>( + first, hit, hit && (first == last), hit.length(), hit.trees); +} + +////////////////////////////////// +template <typename CharT, typename ParserT, typename SkipT> +inline tree_parse_info<CharT const*> +pt_parse( + CharT const* str, + parser<ParserT> const& p, + SkipT const& skip) +{ + CharT const* last = str; + while (*last) + last++; + return pt_parse(str, last, p, skip); +} + +////////////////////////////////// +template <typename CharT, typename ParserT> +inline tree_parse_info<CharT const*> +pt_parse( + CharT const* str, + parser<ParserT> const& parser) +{ + CharT const* last = str; + while (*last) + { + last++; + } + return pt_parse(str, last, parser); +} + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + diff --git a/boost/spirit/home/classic/tree/parse_tree_fwd.hpp b/boost/spirit/home/classic/tree/parse_tree_fwd.hpp new file mode 100644 index 0000000000..5e994594ab --- /dev/null +++ b/boost/spirit/home/classic/tree/parse_tree_fwd.hpp @@ -0,0 +1,39 @@ +/*============================================================================= + Copyright (c) 2006 Tobias Schwinger + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_TREE_PARSE_TREE_FWD_HPP) +#define BOOST_SPIRIT_TREE_PARSE_TREE_FWD_HPP + +#include <boost/spirit/home/classic/namespace.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + template < + typename MatchPolicyT, + typename NodeFactoryT, + typename T = nil_t + > + struct pt_tree_policy; + + template < + typename IteratorT, + typename NodeFactoryT = node_val_data_factory<nil_t>, + typename T = nil_t + > + struct pt_match_policy; + + template <typename T> + struct gen_pt_node_parser; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + diff --git a/boost/spirit/home/classic/tree/parse_tree_utils.hpp b/boost/spirit/home/classic/tree/parse_tree_utils.hpp new file mode 100644 index 0000000000..105d80eb13 --- /dev/null +++ b/boost/spirit/home/classic/tree/parse_tree_utils.hpp @@ -0,0 +1,64 @@ +/*============================================================================= + Copyright (c) 2001-2003 Daniel Nuffer + Copyright (c) 2001-2007 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ + +#if !defined(PARSE_TREE_UTILS_HPP) +#define PARSE_TREE_UTILS_HPP + +#include <utility> // for std::pair + +#include <boost/spirit/home/classic/tree/parse_tree.hpp> // needed for parse tree generation + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { +namespace spirit { +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// +// The function 'get_first_leaf' returnes a reference to the first leaf node +// of the given parsetree. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename T> +tree_node<T> const & +get_first_leaf (tree_node<T> const &node); + +/////////////////////////////////////////////////////////////////////////////// +// +// The function 'find_node' finds a specified node through recursive search. +// If the return value is true, the variable to which points the parameter +// 'found_node' will contain the address of the node with the given rule_id. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename T> +bool +find_node (tree_node<T> const &node, parser_id node_to_search, + tree_node<T> const **found_node); + +/////////////////////////////////////////////////////////////////////////////// +// +// The function 'get_node_range' return a pair of iterators pointing at the +// range, which containes the elements of a specified node. It's very useful +// for locating all information related with a specified node. +// +/////////////////////////////////////////////////////////////////////////////// +template <typename T> +bool +get_node_range (tree_node<T> const &node, parser_id node_to_search, + std::pair<typename tree_node<T>::const_tree_iterator, + typename tree_node<T>::const_tree_iterator> &nodes); + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END +} // namespace spirit +} // namespace boost + +#include "boost/spirit/home/classic/tree/impl/parse_tree_utils.ipp" + +#endif // !defined(PARSE_TREE_UTILS_HPP) diff --git a/boost/spirit/home/classic/tree/parsetree.dtd b/boost/spirit/home/classic/tree/parsetree.dtd new file mode 100644 index 0000000000..9d847c746c --- /dev/null +++ b/boost/spirit/home/classic/tree/parsetree.dtd @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="ISO-8859-1"?> +<!-- This DTD is used for the output of Spirit parse tree's through --> +<!-- the boost::spirit::tree_to_xml functions. --> +<!-- Copyright (c) 2001-2007 Hartmut Kaiser --> +<!-- Distribution 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) --> +<!ELEMENT parsetree (parsenode)> +<!ATTLIST parsetree + version CDATA "1.0" +> +<!ELEMENT parsenode ((value | token)?, parsenode*)> +<!ATTLIST parsenode + rule CDATA #IMPLIED +> +<!ELEMENT value (#PCDATA | token)*> +<!ELEMENT token (#PCDATA)> +<!ATTLIST token + id CDATA #REQUIRED + is_root CDATA "0" +> diff --git a/boost/spirit/home/classic/tree/tree_to_xml.hpp b/boost/spirit/home/classic/tree/tree_to_xml.hpp new file mode 100644 index 0000000000..0ef3aa3bb7 --- /dev/null +++ b/boost/spirit/home/classic/tree/tree_to_xml.hpp @@ -0,0 +1,116 @@ +/*============================================================================= + Copyright (c) 2001-2007 Hartmut Kaiser + 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) +=============================================================================*/ + +#if !defined(TREE_TO_XML_HPP) +#define TREE_TO_XML_HPP + +#include <boost/spirit/home/classic/namespace.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + namespace impl { + template <typename CharT> struct default_string; + } + +/////////////////////////////////////////////////////////////////////////////// +// +// Dump a parse tree as a xml stream +// +// The functions 'tree_to_xml' can be used to output a parse tree as a xml +// stream into the given ostream. The parameters have the following +// meaning: +// +// mandatory parameters: +// ostrm The output stream used for streaming the parse tree. +// tree The parse tree to output. +// +// optional parameters: +// input_line The input line from which the parse tree was +// generated (if given, it is used to output a comment +// containing this line). +// id_to_name A map, which is used for converting the rule id's contained +// in the parse tree to readable strings. Here a auxiliary +// associative container can be used, which maps a rule_id to +// a std::string (i.e. a std::map<rule_id, std::string>). +// get_token_id +// A function or functor, which takes an instance of a token +// and which should return a token id (i.e. something like +// 'int f(char const c)'). +// get_token_value +// A function or functor, which takes an instance of a token +// and which should return a readable representation of this +// token (i.e. something like 'std::string f(char const c)'). +// +// The structure of the generated xml stream conforms to the DTD given in the +// file 'parsetree.dtd'. This file is located in the spirit/tree directory. +// +/////////////////////////////////////////////////////////////////////////////// + + template < + typename CharT, typename TreeNodeT, typename AssocContainerT, + typename GetIdT, typename GetValueT + > + inline void + basic_tree_to_xml (std::basic_ostream<CharT> &ostrm, TreeNodeT const &tree, + std::basic_string<CharT> const &input_line, + AssocContainerT const& id_to_name, GetIdT const &get_token_id, + GetValueT const &get_token_value); + + template <typename CharT, typename TreeNodeT, typename AssocContainerT> + inline void + basic_tree_to_xml (std::basic_ostream<CharT> &ostrm, TreeNodeT const &tree, + std::basic_string<CharT> const &input_line, + AssocContainerT const& id_to_name); + + template <typename CharT, typename TreeNodeT> + inline void + basic_tree_to_xml (std::basic_ostream<CharT> &ostrm, TreeNodeT const &tree, + std::basic_string<CharT> const &input_line = + impl::default_string<CharT>::get()); + + /////////////////////////////////////////////////////////////////////////// + template < + typename TreeNodeT, typename AssocContainerT, + typename GetIdT, typename GetValueT + > + inline void + tree_to_xml (std::ostream &ostrm, TreeNodeT const &tree, + std::string const &input_line, AssocContainerT const& id_to_name, + GetIdT const &get_token_id, GetValueT const &get_token_value) + { + basic_tree_to_xml<char>(ostrm, tree, input_line, id_to_name, + get_token_id, get_token_value); + } + + template <typename TreeNodeT, typename AssocContainerT> + inline void + tree_to_xml (std::ostream &ostrm, TreeNodeT const &tree, + std::string const &input_line, AssocContainerT const& id_to_name) + { + basic_tree_to_xml<char>(ostrm, tree, input_line, id_to_name); + } + + template <typename TreeNodeT> + inline void + tree_to_xml (std::ostream &ostrm, TreeNodeT const &tree, + std::string const &input_line = "") + { + basic_tree_to_xml<char>(ostrm, tree, input_line); + } + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#include <boost/spirit/home/classic/tree/impl/tree_to_xml.ipp> + +#endif // !defined(TREE_TO_XML_HPP) + diff --git a/boost/spirit/home/classic/tree/typeof.hpp b/boost/spirit/home/classic/tree/typeof.hpp new file mode 100644 index 0000000000..2d25512c81 --- /dev/null +++ b/boost/spirit/home/classic/tree/typeof.hpp @@ -0,0 +1,80 @@ +/*============================================================================= + Copyright (c) 2006 Tobias Schwinger + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_TREE_TYPEOF_HPP) +#define BOOST_SPIRIT_TREE_TYPEOF_HPP + +#include <boost/typeof/typeof.hpp> + +#include <boost/spirit/home/classic/core/typeof.hpp> + +#include <boost/spirit/home/classic/tree/common_fwd.hpp> +#include <boost/spirit/home/classic/tree/parse_tree_fwd.hpp> +#include <boost/spirit/home/classic/tree/ast_fwd.hpp> + + +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() + + +// common.hpp (has forward header) + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::tree_node,1) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::node_iter_data,2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::node_iter_data_factory,1) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::node_val_data_factory,1) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::node_all_val_data_factory,1) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::tree_match,3) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::tree_policy) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::common_tree_match_policy,4) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::common_tree_tree_policy,2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::no_tree_gen_node_parser,1) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::leaf_node_parser,1) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::node_parser,2) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::discard_node_op) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::reduced_node_op) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::infix_node_op) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::discard_first_node_op) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::discard_last_node_op) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::inner_node_op) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::action_directive_parser,2) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::access_match_action) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::access_match_action::action,2) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::access_node_action) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::access_node_action::action,2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::tree_parse_info,3) + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::node_iter_data,1) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::node_iter_data_factory<BOOST_SPIRIT_CLASSIC_NS::nil_t>) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::node_val_data_factory<BOOST_SPIRIT_CLASSIC_NS::nil_t>) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::node_all_val_data_factory<BOOST_SPIRIT_CLASSIC_NS::nil_t>) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::tree_match,2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::tree_match,1) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::tree_parse_info,2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::tree_parse_info,1) + + +// parse_tree.hpp (has forward header) + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::pt_tree_policy,2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::pt_match_policy,2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::gen_pt_node_parser,1) + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::pt_match_policy,1) + + +// ast.hpp (has forward header) + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::ast_tree_policy,2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::ast_match_policy,2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::gen_ast_node_parser,1) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::root_node_op) + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::ast_match_policy,1) + + +#endif + diff --git a/boost/spirit/home/classic/utility.hpp b/boost/spirit/home/classic/utility.hpp new file mode 100644 index 0000000000..8eec51a7f7 --- /dev/null +++ b/boost/spirit/home/classic/utility.hpp @@ -0,0 +1,40 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001-2003 Daniel Nuffer + Copyright (c) 2001-2003 Hartmut Kaiser + Copyright (c) 2002-2003 Martin Wille + Copyright (c) 2002 Juan Carlos Arevalo-Baeza + Copyright (c) 2002 Raghavendra Satish + Copyright (c) 2002 Jeff Westfahl + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_UTILITY_MAIN_HPP) +#define BOOST_SPIRIT_UTILITY_MAIN_HPP + +#include <boost/spirit/home/classic/version.hpp> + +/////////////////////////////////////////////////////////////////////////////// +// +// Master header for Spirit.Utilities +// +/////////////////////////////////////////////////////////////////////////////// + +// Utility.Parsers +#include <boost/spirit/home/classic/utility/chset.hpp> +#include <boost/spirit/home/classic/utility/chset_operators.hpp> +#include <boost/spirit/home/classic/utility/escape_char.hpp> +#include <boost/spirit/home/classic/utility/functor_parser.hpp> +#include <boost/spirit/home/classic/utility/loops.hpp> +#include <boost/spirit/home/classic/utility/confix.hpp> +#include <boost/spirit/home/classic/utility/lists.hpp> +#include <boost/spirit/home/classic/utility/distinct.hpp> + +// Utility.Support +#include <boost/spirit/home/classic/utility/flush_multi_pass.hpp> +#include <boost/spirit/home/classic/utility/scoped_lock.hpp> + + +#endif // !defined(BOOST_SPIRIT_UTILITY_MAIN_HPP) diff --git a/boost/spirit/home/classic/utility/chset.hpp b/boost/spirit/home/classic/utility/chset.hpp new file mode 100644 index 0000000000..3635456424 --- /dev/null +++ b/boost/spirit/home/classic/utility/chset.hpp @@ -0,0 +1,187 @@ +/*============================================================================= + Copyright (c) 2001-2003 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_CHSET_HPP +#define BOOST_SPIRIT_CHSET_HPP + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/shared_ptr.hpp> +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/primitives/primitives.hpp> +#include <boost/spirit/home/classic/utility/impl/chset/basic_chset.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +namespace utility { namespace impl { + + // This is here because some compilers choke on out-of-line member + // template functions. And we don't want to put the whole algorithm + // in the chset constructor in the class definition. + template <typename CharT, typename CharT2> + void construct_chset(boost::shared_ptr<basic_chset<CharT> >& ptr, + CharT2 const* definition); + +}} // namespace utility::impl + +/////////////////////////////////////////////////////////////////////////////// +// +// chset class +// +/////////////////////////////////////////////////////////////////////////////// +template <typename CharT = char> +class chset: public char_parser<chset<CharT> > { + +public: + chset(); + chset(chset const& arg_); + explicit chset(CharT arg_); + explicit chset(anychar_parser arg_); + explicit chset(nothing_parser arg_); + explicit chset(chlit<CharT> const& arg_); + explicit chset(range<CharT> const& arg_); + explicit chset(negated_char_parser<chlit<CharT> > const& arg_); + explicit chset(negated_char_parser<range<CharT> > const& arg_); + + template <typename CharT2> + explicit chset(CharT2 const* definition) + : ptr(new basic_chset<CharT>()) + { + utility::impl::construct_chset(ptr, definition); + } + ~chset(); + + chset& operator=(chset const& rhs); + chset& operator=(CharT rhs); + chset& operator=(anychar_parser rhs); + chset& operator=(nothing_parser rhs); + chset& operator=(chlit<CharT> const& rhs); + chset& operator=(range<CharT> const& rhs); + chset& operator=(negated_char_parser<chlit<CharT> > const& rhs); + chset& operator=(negated_char_parser<range<CharT> > const& rhs); + + void set(range<CharT> const& arg_); + void set(negated_char_parser<chlit<CharT> > const& arg_); + void set(negated_char_parser<range<CharT> > const& arg_); + + void clear(range<CharT> const& arg_); + void clear(negated_char_parser<range<CharT> > const& arg_); + bool test(CharT ch) const; + chset& inverse(); + void swap(chset& x); + + chset& operator|=(chset const& x); + chset& operator&=(chset const& x); + chset& operator-=(chset const& x); + chset& operator^=(chset const& x); + +private: + + boost::shared_ptr<basic_chset<CharT> > ptr; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// Generator functions +// +/////////////////////////////////////////////////////////////////////////////// +template <typename CharT> +inline chset<CharT> +chset_p(chlit<CharT> const& arg_) +{ return chset<CharT>(arg_); } + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +chset_p(range<CharT> const& arg_) +{ return chset<CharT>(arg_); } + +template <typename CharT> +inline chset<CharT> +chset_p(negated_char_parser<chlit<CharT> > const& arg_) +{ return chset<CharT>(arg_); } + +template <typename CharT> +inline chset<CharT> +chset_p(negated_char_parser<range<CharT> > const& arg_) +{ return chset<CharT>(arg_); } + +////////////////////////////////// +inline chset<char> +chset_p(char const* init) +{ return chset<char>(init); } + +////////////////////////////////// +inline chset<wchar_t> +chset_p(wchar_t const* init) +{ return chset<wchar_t>(init); } + +////////////////////////////////// +inline chset<char> +chset_p(char ch) +{ return chset<char>(ch); } + +////////////////////////////////// +inline chset<wchar_t> +chset_p(wchar_t ch) +{ return chset<wchar_t>(ch); } + +////////////////////////////////// +inline chset<int> +chset_p(int ch) +{ return chset<int>(ch); } + +////////////////////////////////// +inline chset<unsigned int> +chset_p(unsigned int ch) +{ return chset<unsigned int>(ch); } + +////////////////////////////////// +inline chset<short> +chset_p(short ch) +{ return chset<short>(ch); } + +#if !defined(BOOST_NO_INTRINSIC_WCHAR_T) +////////////////////////////////// +inline chset<unsigned short> +chset_p(unsigned short ch) +{ return chset<unsigned short>(ch); } +#endif +////////////////////////////////// +inline chset<long> +chset_p(long ch) +{ return chset<long>(ch); } + +////////////////////////////////// +inline chset<unsigned long> +chset_p(unsigned long ch) +{ return chset<unsigned long>(ch); } + +#ifdef BOOST_HAS_LONG_LONG +////////////////////////////////// +inline chset< ::boost::long_long_type> +chset_p( ::boost::long_long_type ch) +{ return chset< ::boost::long_long_type>(ch); } + +////////////////////////////////// +inline chset< ::boost::ulong_long_type> +chset_p( ::boost::ulong_long_type ch) +{ return chset< ::boost::ulong_long_type>(ch); } +#endif + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + +#include <boost/spirit/home/classic/utility/impl/chset.ipp> +#include <boost/spirit/home/classic/utility/chset_operators.hpp> diff --git a/boost/spirit/home/classic/utility/chset_operators.hpp b/boost/spirit/home/classic/utility/chset_operators.hpp new file mode 100644 index 0000000000..d42b5faae4 --- /dev/null +++ b/boost/spirit/home/classic/utility/chset_operators.hpp @@ -0,0 +1,402 @@ +/*============================================================================= + Copyright (c) 2001-2003 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_CHSET_OPERATORS_HPP +#define BOOST_SPIRIT_CHSET_OPERATORS_HPP + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/utility/chset.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// +// chset free operators +// +// Where a and b are both chsets, implements: +// +// a | b, a & b, a - b, a ^ b +// +// Where a is a chset, implements: +// +// ~a +// +/////////////////////////////////////////////////////////////////////////////// +template <typename CharT> +chset<CharT> +operator~(chset<CharT> const& a); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator|(chset<CharT> const& a, chset<CharT> const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator&(chset<CharT> const& a, chset<CharT> const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator-(chset<CharT> const& a, chset<CharT> const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator^(chset<CharT> const& a, chset<CharT> const& b); + +/////////////////////////////////////////////////////////////////////////////// +// +// range <--> chset free operators +// +// Where a is a chset and b is a range, and vice-versa, implements: +// +// a | b, a & b, a - b, a ^ b +// +/////////////////////////////////////////////////////////////////////////////// +template <typename CharT> +chset<CharT> +operator|(chset<CharT> const& a, range<CharT> const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator&(chset<CharT> const& a, range<CharT> const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator-(chset<CharT> const& a, range<CharT> const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator^(chset<CharT> const& a, range<CharT> const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator|(range<CharT> const& a, chset<CharT> const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator&(range<CharT> const& a, chset<CharT> const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator-(range<CharT> const& a, chset<CharT> const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator^(range<CharT> const& a, chset<CharT> const& b); + +/////////////////////////////////////////////////////////////////////////////// +// +// chlit <--> chset free operators +// +// Where a is a chset and b is a chlit, and vice-versa, implements: +// +// a | b, a & b, a - b, a ^ b +// +/////////////////////////////////////////////////////////////////////////////// +template <typename CharT> +chset<CharT> +operator|(chset<CharT> const& a, chlit<CharT> const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator&(chset<CharT> const& a, chlit<CharT> const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator-(chset<CharT> const& a, chlit<CharT> const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator^(chset<CharT> const& a, chlit<CharT> const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator|(chlit<CharT> const& a, chset<CharT> const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator&(chlit<CharT> const& a, chset<CharT> const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator-(chlit<CharT> const& a, chset<CharT> const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator^(chlit<CharT> const& a, chset<CharT> const& b); + +/////////////////////////////////////////////////////////////////////////////// +// +// negated_char_parser<range> <--> chset free operators +// +// Where a is a chset and b is a range, and vice-versa, implements: +// +// a | b, a & b, a - b, a ^ b +// +/////////////////////////////////////////////////////////////////////////////// +template <typename CharT> +chset<CharT> +operator|(chset<CharT> const& a, negated_char_parser<range<CharT> > const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator&(chset<CharT> const& a, negated_char_parser<range<CharT> > const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator-(chset<CharT> const& a, negated_char_parser<range<CharT> > const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator^(chset<CharT> const& a, negated_char_parser<range<CharT> > const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator|(negated_char_parser<range<CharT> > const& a, chset<CharT> const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator&(negated_char_parser<range<CharT> > const& a, chset<CharT> const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator-(negated_char_parser<range<CharT> > const& a, chset<CharT> const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator^(negated_char_parser<range<CharT> > const& a, chset<CharT> const& b); + +/////////////////////////////////////////////////////////////////////////////// +// +// negated_char_parser<chlit> <--> chset free operators +// +// Where a is a chset and b is a chlit, and vice-versa, implements: +// +// a | b, a & b, a - b, a ^ b +// +/////////////////////////////////////////////////////////////////////////////// +template <typename CharT> +chset<CharT> +operator|(chset<CharT> const& a, negated_char_parser<chlit<CharT> > const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator&(chset<CharT> const& a, negated_char_parser<chlit<CharT> > const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator-(chset<CharT> const& a, negated_char_parser<chlit<CharT> > const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator^(chset<CharT> const& a, negated_char_parser<chlit<CharT> > const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator|(negated_char_parser<chlit<CharT> > const& a, chset<CharT> const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator&(negated_char_parser<chlit<CharT> > const& a, chset<CharT> const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator-(negated_char_parser<chlit<CharT> > const& a, chset<CharT> const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator^(negated_char_parser<chlit<CharT> > const& a, chset<CharT> const& b); + +/////////////////////////////////////////////////////////////////////////////// +// +// literal primitives <--> chset free operators +// +// Where a is a chset and b is a literal primitive, +// and vice-versa, implements: +// +// a | b, a & b, a - b, a ^ b +// +/////////////////////////////////////////////////////////////////////////////// +template <typename CharT> +chset<CharT> +operator|(chset<CharT> const& a, CharT b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator&(chset<CharT> const& a, CharT b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator-(chset<CharT> const& a, CharT b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator^(chset<CharT> const& a, CharT b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator|(CharT a, chset<CharT> const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator&(CharT a, chset<CharT> const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator-(CharT a, chset<CharT> const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator^(CharT a, chset<CharT> const& b); + +/////////////////////////////////////////////////////////////////////////////// +// +// anychar_parser <--> chset free operators +// +// Where a is chset and b is a anychar_parser, and vice-versa, implements: +// +// a | b, a & b, a - b, a ^ b +// +/////////////////////////////////////////////////////////////////////////////// +template <typename CharT> +chset<CharT> +operator|(chset<CharT> const& a, anychar_parser b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator&(chset<CharT> const& a, anychar_parser b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator-(chset<CharT> const& a, anychar_parser b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator^(chset<CharT> const& a, anychar_parser b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator|(anychar_parser a, chset<CharT> const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator&(anychar_parser a, chset<CharT> const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator-(anychar_parser a, chset<CharT> const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator^(anychar_parser a, chset<CharT> const& b); + +/////////////////////////////////////////////////////////////////////////////// +// +// nothing_parser <--> chset free operators +// +// Where a is chset and b is nothing_parser, and vice-versa, implements: +// +// a | b, a & b, a - b, a ^ b +// +/////////////////////////////////////////////////////////////////////////////// +template <typename CharT> +chset<CharT> +operator|(chset<CharT> const& a, nothing_parser b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator&(chset<CharT> const& a, nothing_parser b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator-(chset<CharT> const& a, nothing_parser b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator^(chset<CharT> const& a, nothing_parser b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator|(nothing_parser a, chset<CharT> const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator&(nothing_parser a, chset<CharT> const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator-(nothing_parser a, chset<CharT> const& b); + +////////////////////////////////// +template <typename CharT> +chset<CharT> +operator^(nothing_parser a, chset<CharT> const& b); + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + +#include <boost/spirit/home/classic/utility/impl/chset_operators.ipp> diff --git a/boost/spirit/home/classic/utility/confix.hpp b/boost/spirit/home/classic/utility/confix.hpp new file mode 100644 index 0000000000..42228ea242 --- /dev/null +++ b/boost/spirit/home/classic/utility/confix.hpp @@ -0,0 +1,405 @@ +/*============================================================================= + Copyright (c) 2002-2003 Hartmut Kaiser + 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_CONFIX_HPP +#define BOOST_SPIRIT_CONFIX_HPP + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/config.hpp> +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/meta/as_parser.hpp> +#include <boost/spirit/home/classic/core/composite/operators.hpp> + +#include <boost/spirit/home/classic/utility/confix_fwd.hpp> +#include <boost/spirit/home/classic/utility/impl/confix.ipp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// +// confix_parser class +// +// Parses a sequence of 3 sub-matches. This class may +// be used to parse structures, where the opening part is possibly +// contained in the expression part and the whole sequence is only +// parsed after seeing the closing part matching the first opening +// subsequence. Example: C-comments: +// +// /* This is a C-comment */ +// +/////////////////////////////////////////////////////////////////////////////// + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(push) +#pragma warning(disable:4512) //assignment operator could not be generated +#endif + +template<typename NestedT = non_nested, typename LexemeT = non_lexeme> +struct confix_parser_gen; + +template < + typename OpenT, typename ExprT, typename CloseT, typename CategoryT, + typename NestedT, typename LexemeT +> +struct confix_parser : + public parser< + confix_parser<OpenT, ExprT, CloseT, CategoryT, NestedT, LexemeT> + > +{ + typedef + confix_parser<OpenT, ExprT, CloseT, CategoryT, NestedT, LexemeT> + self_t; + + confix_parser(OpenT const &open_, ExprT const &expr_, CloseT const &close_) + : open(open_), expr(expr_), close(close_) + {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + return impl::confix_parser_type<CategoryT>:: + parse(NestedT(), LexemeT(), *this, scan, open, expr, close); + } + +private: + + typename as_parser<OpenT>::type::embed_t open; + typename as_parser<ExprT>::type::embed_t expr; + typename as_parser<CloseT>::type::embed_t close; +}; + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(pop) +#endif + +/////////////////////////////////////////////////////////////////////////////// +// +// Confix parser generator template +// +// This is a helper for generating a correct confix_parser<> from +// auxiliary parameters. There are the following types supported as +// parameters yet: parsers, single characters and strings (see +// as_parser). +// +// If the body parser is an action_parser_category type parser (a parser +// with an attached semantic action) we have to do something special. This +// happens, if the user wrote something like: +// +// confix_p(open, body[f], close) +// +// where 'body' is the parser matching the body of the confix sequence +// and 'f' is a functor to be called after matching the body. If we would +// do nothing, the resulting code would parse the sequence as follows: +// +// start >> (body[f] - close) >> close +// +// what in most cases is not what the user expects. +// (If this _is_ what you've expected, then please use the confix_p +// generator function 'direct()', which will inhibit +// re-attaching the actor to the body parser). +// +// To make the confix parser behave as expected: +// +// start >> (body - close)[f] >> close +// +// the actor attached to the 'body' parser has to be re-attached to the +// (body - close) parser construct, which will make the resulting confix +// parser 'do the right thing'. This refactoring is done by the help of +// the refactoring parsers (see the files refactoring.[hi]pp). +// +// Additionally special care must be taken, if the body parser is a +// unary_parser_category type parser as +// +// confix_p(open, *anychar_p, close) +// +// which without any refactoring would result in +// +// start >> (*anychar_p - close) >> close +// +// and will not give the expected result (*anychar_p will eat up all the +// input up to the end of the input stream). So we have to refactor this +// into: +// +// start >> *(anychar_p - close) >> close +// +// what will give the correct result. +// +// The case, where the body parser is a combination of the two mentioned +// problems (i.e. the body parser is a unary parser with an attached +// action), is handled accordingly too: +// +// confix_p(start, (*anychar_p)[f], end) +// +// will be parsed as expected: +// +// start >> (*(anychar_p - end))[f] >> end. +// +/////////////////////////////////////////////////////////////////////////////// + +template<typename NestedT, typename LexemeT> +struct confix_parser_gen +{ + // Generic generator function for creation of concrete confix parsers + + template<typename StartT, typename ExprT, typename EndT> + struct paren_op_result_type + { + typedef confix_parser< + typename as_parser<StartT>::type, + typename as_parser<ExprT>::type, + typename as_parser<EndT>::type, + typename as_parser<ExprT>::type::parser_category_t, + NestedT, + LexemeT + > type; + }; + + template<typename StartT, typename ExprT, typename EndT> + typename paren_op_result_type<StartT, ExprT, EndT>::type + operator()(StartT const &start_, ExprT const &expr_, EndT const &end_) const + { + typedef typename paren_op_result_type<StartT,ExprT,EndT>::type + return_t; + + return return_t( + as_parser<StartT>::convert(start_), + as_parser<ExprT>::convert(expr_), + as_parser<EndT>::convert(end_) + ); + } + + // Generic generator function for creation of concrete confix parsers + // which have an action directly attached to the ExprT part of the + // parser (see comment above, no automatic refactoring) + + template<typename StartT, typename ExprT, typename EndT> + struct direct_result_type + { + typedef confix_parser< + typename as_parser<StartT>::type, + typename as_parser<ExprT>::type, + typename as_parser<EndT>::type, + plain_parser_category, // do not re-attach action + NestedT, + LexemeT + > type; + }; + + template<typename StartT, typename ExprT, typename EndT> + typename direct_result_type<StartT,ExprT,EndT>::type + direct(StartT const &start_, ExprT const &expr_, EndT const &end_) const + { + typedef typename direct_result_type<StartT,ExprT,EndT>::type + return_t; + + return return_t( + as_parser<StartT>::convert(start_), + as_parser<ExprT>::convert(expr_), + as_parser<EndT>::convert(end_) + ); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// Predefined non_nested confix parser generators +// +/////////////////////////////////////////////////////////////////////////////// + +const confix_parser_gen<non_nested, non_lexeme> confix_p = + confix_parser_gen<non_nested, non_lexeme>(); + +/////////////////////////////////////////////////////////////////////////////// +// +// Comments are special types of confix parsers +// +// Comment parser generator template. This is a helper for generating a +// correct confix_parser<> from auxiliary parameters, which is able to +// parse comment constructs: (StartToken >> Comment text >> EndToken). +// +// There are the following types supported as parameters yet: parsers, +// single characters and strings (see as_parser). +// +// There are two diffenerent predefined comment parser generators +// (comment_p and comment_nest_p, see below), which may be used for +// creating special comment parsers in two different ways. +// +// If these are used with one parameter, a comment starting with the given +// first parser parameter up to the end of the line is matched. So for +// instance the following parser matches C++ style comments: +// +// comment_p("//"). +// +// If these are used with two parameters, a comment starting with the +// first parser parameter up to the second parser parameter is matched. +// For instance a C style comment parser should be constrcuted as: +// +// comment_p("/*", "*/"). +// +// Please note, that a comment is parsed implicitly as if the whole +// comment_p(...) statement were embedded into a lexeme_d[] directive. +// +/////////////////////////////////////////////////////////////////////////////// + +template<typename NestedT> +struct comment_parser_gen +{ + // Generic generator function for creation of concrete comment parsers + // from an open token. The newline parser eol_p is used as the + // closing token. + + template<typename StartT> + struct paren_op1_result_type + { + typedef confix_parser< + typename as_parser<StartT>::type, + kleene_star<anychar_parser>, + alternative<eol_parser, end_parser>, + unary_parser_category, // there is no action to re-attach + NestedT, + is_lexeme // insert implicit lexeme_d[] + > + type; + }; + + template<typename StartT> + typename paren_op1_result_type<StartT>::type + operator() (StartT const &start_) const + { + typedef typename paren_op1_result_type<StartT>::type + return_t; + + return return_t( + as_parser<StartT>::convert(start_), + *anychar_p, + eol_p | end_p + ); + } + + // Generic generator function for creation of concrete comment parsers + // from an open and a close tokens. + + template<typename StartT, typename EndT> + struct paren_op2_result_type + { + typedef confix_parser< + typename as_parser<StartT>::type, + kleene_star<anychar_parser>, + typename as_parser<EndT>::type, + unary_parser_category, // there is no action to re-attach + NestedT, + is_lexeme // insert implicit lexeme_d[] + > type; + }; + + template<typename StartT, typename EndT> + typename paren_op2_result_type<StartT,EndT>::type + operator() (StartT const &start_, EndT const &end_) const + { + typedef typename paren_op2_result_type<StartT,EndT>::type + return_t; + + return return_t( + as_parser<StartT>::convert(start_), + *anychar_p, + as_parser<EndT>::convert(end_) + ); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// Predefined non_nested comment parser generator +// +/////////////////////////////////////////////////////////////////////////////// + +const comment_parser_gen<non_nested> comment_p = + comment_parser_gen<non_nested>(); + +/////////////////////////////////////////////////////////////////////////////// +// +// comment_nest_parser class +// +// Parses a nested comments. +// Example: nested PASCAL-comments: +// +// { This is a { nested } PASCAL-comment } +// +/////////////////////////////////////////////////////////////////////////////// + +template<typename OpenT, typename CloseT> +struct comment_nest_parser: + public parser<comment_nest_parser<OpenT, CloseT> > +{ + typedef comment_nest_parser<OpenT, CloseT> self_t; + + comment_nest_parser(OpenT const &open_, CloseT const &close_): + open(open_), close(close_) + {} + + template<typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const &scan) const + { + return do_parse( + open >> *(*this | (anychar_p - close)) >> close, + scan); + } + +private: + template<typename ParserT, typename ScannerT> + typename parser_result<self_t, ScannerT>::type + do_parse(ParserT const &p, ScannerT const &scan) const + { + return + impl::contiguous_parser_parse< + typename parser_result<ParserT, ScannerT>::type + >(p, scan, scan); + } + + typename as_parser<OpenT>::type::embed_t open; + typename as_parser<CloseT>::type::embed_t close; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// Predefined nested comment parser generator +// +/////////////////////////////////////////////////////////////////////////////// + +template<typename OpenT, typename CloseT> +struct comment_nest_p_result +{ + typedef comment_nest_parser< + typename as_parser<OpenT>::type, + typename as_parser<CloseT>::type + > type; +}; + +template<typename OpenT, typename CloseT> +inline typename comment_nest_p_result<OpenT,CloseT>::type +comment_nest_p(OpenT const &open, CloseT const &close) +{ + typedef typename comment_nest_p_result<OpenT,CloseT>::type + result_t; + + return result_t( + as_parser<OpenT>::convert(open), + as_parser<CloseT>::convert(close) + ); +} + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif diff --git a/boost/spirit/home/classic/utility/confix_fwd.hpp b/boost/spirit/home/classic/utility/confix_fwd.hpp new file mode 100644 index 0000000000..24e2236233 --- /dev/null +++ b/boost/spirit/home/classic/utility/confix_fwd.hpp @@ -0,0 +1,39 @@ +/*============================================================================= + Copyright (c) 2006 Tobias Schwinger + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_CONFIX_FWD_HPP) +#define BOOST_SPIRIT_CONFIX_FWD_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + struct is_nested; + struct non_nested; + struct is_lexeme; + struct non_lexeme; + + template < + typename OpenT, typename ExprT, typename CloseT, + typename CategoryT = plain_parser_category, + typename NestedT = non_nested, typename LexemeT = non_lexeme + > + struct confix_parser; + + template<typename OpenT, typename CloseT> + struct comment_nest_parser; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + + diff --git a/boost/spirit/home/classic/utility/distinct.hpp b/boost/spirit/home/classic/utility/distinct.hpp new file mode 100644 index 0000000000..b66d409f5d --- /dev/null +++ b/boost/spirit/home/classic/utility/distinct.hpp @@ -0,0 +1,229 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2003 Vaclav Vesely + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_DISTINCT_HPP) +#define BOOST_SPIRIT_DISTINCT_HPP + +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/core/primitives/primitives.hpp> +#include <boost/spirit/home/classic/core/composite/operators.hpp> +#include <boost/spirit/home/classic/core/composite/directives.hpp> +#include <boost/spirit/home/classic/core/composite/epsilon.hpp> +#include <boost/spirit/home/classic/core/non_terminal/rule.hpp> +#include <boost/spirit/home/classic/utility/chset.hpp> + +#include <boost/spirit/home/classic/utility/distinct_fwd.hpp> + +namespace boost { + namespace spirit { + BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +//----------------------------------------------------------------------------- +// distinct_parser class + +template <typename CharT, typename TailT> +class distinct_parser +{ +public: + typedef + contiguous< + sequence< + chseq<CharT const*>, + negated_empty_match_parser< + TailT + > + > + > + result_t; + + distinct_parser() + : tail(chset<CharT>()) + { + } + + explicit distinct_parser(parser<TailT> const & tail_) + : tail(tail_.derived()) + { + } + + explicit distinct_parser(CharT const* letters) + : tail(chset_p(letters)) + { + } + + result_t operator()(CharT const* str) const + { + return lexeme_d[chseq_p(str) >> ~epsilon_p(tail)]; + } + + TailT tail; +}; + +//----------------------------------------------------------------------------- +// distinct_directive class + +template <typename CharT, typename TailT> +class distinct_directive +{ +public: + template<typename ParserT> + struct result { + typedef + contiguous< + sequence< + ParserT, + negated_empty_match_parser< + TailT + > + > + > + type; + }; + + distinct_directive() + : tail(chset<CharT>()) + { + } + + explicit distinct_directive(CharT const* letters) + : tail(chset_p(letters)) + { + } + + explicit distinct_directive(parser<TailT> const & tail_) + : tail(tail_.derived()) + { + } + + template<typename ParserT> + typename result<typename as_parser<ParserT>::type>::type + operator[](ParserT const &subject) const + { + return + lexeme_d[as_parser<ParserT>::convert(subject) >> ~epsilon_p(tail)]; + } + + TailT tail; +}; + +//----------------------------------------------------------------------------- +// dynamic_distinct_parser class + +template <typename ScannerT> +class dynamic_distinct_parser +{ +public: + typedef typename ScannerT::value_t char_t; + + typedef + rule< + typename no_actions_scanner< + typename lexeme_scanner<ScannerT>::type + >::type + > + tail_t; + + typedef + contiguous< + sequence< + chseq<char_t const*>, + negated_empty_match_parser< + tail_t + > + > + > + result_t; + + dynamic_distinct_parser() + : tail(nothing_p) + { + } + + template<typename ParserT> + explicit dynamic_distinct_parser(parser<ParserT> const & tail_) + : tail(tail_.derived()) + { + } + + explicit dynamic_distinct_parser(char_t const* letters) + : tail(chset_p(letters)) + { + } + + result_t operator()(char_t const* str) const + { + return lexeme_d[chseq_p(str) >> ~epsilon_p(tail)]; + } + + tail_t tail; +}; + +//----------------------------------------------------------------------------- +// dynamic_distinct_directive class + +template <typename ScannerT> +class dynamic_distinct_directive +{ +public: + typedef typename ScannerT::value_t char_t; + + typedef + rule< + typename no_actions_scanner< + typename lexeme_scanner<ScannerT>::type + >::type + > + tail_t; + + template<typename ParserT> + struct result { + typedef + contiguous< + sequence< + ParserT, + negated_empty_match_parser< + tail_t + > + > + > + type; + }; + + dynamic_distinct_directive() + : tail(nothing_p) + { + } + + template<typename ParserT> + explicit dynamic_distinct_directive(parser<ParserT> const & tail_) + : tail(tail_.derived()) + { + } + + explicit dynamic_distinct_directive(char_t const* letters) + : tail(chset_p(letters)) + { + } + + template<typename ParserT> + typename result<typename as_parser<ParserT>::type>::type + operator[](ParserT const &subject) const + { + return + lexeme_d[as_parser<ParserT>::convert(subject) >> ~epsilon_p(tail)]; + } + + tail_t tail; +}; + +//----------------------------------------------------------------------------- + BOOST_SPIRIT_CLASSIC_NAMESPACE_END + } // namespace spirit +} // namespace boost + +#endif // !defined(BOOST_SPIRIT_DISTINCT_HPP) diff --git a/boost/spirit/home/classic/utility/distinct_fwd.hpp b/boost/spirit/home/classic/utility/distinct_fwd.hpp new file mode 100644 index 0000000000..368d1f0162 --- /dev/null +++ b/boost/spirit/home/classic/utility/distinct_fwd.hpp @@ -0,0 +1,37 @@ +/*============================================================================= + Copyright (c) 2006 Tobias Schwinger + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_DISTINCT_FWD_HPP) +#define BOOST_SPIRIT_DISTINCT_FWD_HPP + +#include <boost/spirit/home/classic/namespace.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + template<typename CharT> class chset; + + template <typename CharT = char, typename TailT = chset<CharT> > + class distinct_parser; + + template <typename CharT = char, typename TailT = chset<CharT> > + class distinct_directive; + + template <typename ScannerT = scanner<> > + class dynamic_distinct_parser; + + template <typename ScannerT = scanner<> > + class dynamic_distinct_directive; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + + diff --git a/boost/spirit/home/classic/utility/escape_char.hpp b/boost/spirit/home/classic/utility/escape_char.hpp new file mode 100644 index 0000000000..375402f73a --- /dev/null +++ b/boost/spirit/home/classic/utility/escape_char.hpp @@ -0,0 +1,184 @@ +/*============================================================================= + 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_ESCAPE_CHAR_HPP +#define BOOST_SPIRIT_ESCAPE_CHAR_HPP + +/////////////////////////////////////////////////////////////////////////////// +#include <string> +#include <iterator> +#include <cctype> +#include <boost/limits.hpp> + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/debug.hpp> + +#include <boost/spirit/home/classic/utility/escape_char_fwd.hpp> +#include <boost/spirit/home/classic/utility/impl/escape_char.ipp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// +// escape_char_action class +// +// Links an escape char parser with a user defined semantic action. +// The semantic action may be a function or a functor. A function +// should be compatible with the interface: +// +// void f(CharT ch); +// +// A functor should have a member operator() with a compatible signature +// as above. The matching character is passed into the function/functor. +// This is the default class that character parsers use when dealing with +// the construct: +// +// p[f] +// +// where p is a parser and f is a function or functor. +// +/////////////////////////////////////////////////////////////////////////////// +template < + typename ParserT, typename ActionT, + unsigned long Flags, typename CharT +> +struct escape_char_action +: public unary<ParserT, + parser<escape_char_action<ParserT, ActionT, Flags, CharT> > > +{ + typedef escape_char_action + <ParserT, ActionT, Flags, CharT> self_t; + typedef action_parser_category parser_category_t; + typedef unary<ParserT, parser<self_t> > base_t; + + template <typename ScannerT> + struct result + { + typedef typename match_result<ScannerT, CharT>::type type; + }; + + escape_char_action(ParserT const& p, ActionT const& a) + : base_t(p), actor(a) {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + return impl::escape_char_action_parse<Flags, CharT>:: + parse(scan, *this); + } + + ActionT const& predicate() const { return actor; } + +private: + + ActionT actor; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// escape_char_parser class +// +// The escape_char_parser helps in conjunction with the escape_char_action +// template class (see above) in parsing escaped characters. There are two +// different variants of this parser: one for parsing C style escaped +// characters and one for parsing LEX style escaped characters. +// +// The C style escaped character parser is generated, when the template +// parameter 'Flags' is equal to 'c_escapes' (a constant defined in the +// file impl/escape_char.ipp). This parser recognizes all valid C escape +// character sequences: '\t', '\b', '\f', '\n', '\r', '\"', '\'', '\\' +// and the numeric style escapes '\120' (octal) and '\x2f' (hexadecimal) +// and converts these to their character equivalent, for instance the +// sequence of a backslash and a 'b' is parsed as the character '\b'. +// All other escaped characters are rejected by this parser. +// +// The LEX style escaped character parser is generated, when the template +// parameter 'Flags' is equal to 'lex_escapes' (a constant defined in the +// file impl/escape_char.ipp). This parser recognizes all the C style +// escaped character sequences (as described above) and additionally +// does not reject all other escape sequences. All not mentioned escape +// sequences are converted by the parser to the plain character, for +// instance '\a' will be parsed as 'a'. +// +// All not escaped characters are parsed without modification. +// +/////////////////////////////////////////////////////////////////////////////// + +template <unsigned long Flags, typename CharT> +struct escape_char_action_parser_gen; + +template <unsigned long Flags, typename CharT> +struct escape_char_parser : + public parser<escape_char_parser<Flags, CharT> > { + + // only the values c_escapes and lex_escapes are valid for Flags + BOOST_STATIC_ASSERT(Flags == c_escapes || Flags == lex_escapes); + + typedef escape_char_parser<Flags, CharT> self_t; + typedef + escape_char_action_parser_gen<Flags, CharT> + action_parser_generator_t; + + template <typename ScannerT> + struct result { + + typedef typename match_result<ScannerT, CharT>::type type; + }; + + template <typename ActionT> + escape_char_action<self_t, ActionT, Flags, CharT> + operator[](ActionT const& actor) const + { + return escape_char_action<self_t, ActionT, Flags, CharT>(*this, actor); + } + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const &scan) const + { + return impl::escape_char_parse<CharT>::parse(scan, *this); + } +}; + +template <unsigned long Flags, typename CharT> +struct escape_char_action_parser_gen { + + template <typename ParserT, typename ActionT> + static escape_char_action<ParserT, ActionT, Flags, CharT> + generate (ParserT const &p, ActionT const &actor) + { + typedef + escape_char_action<ParserT, ActionT, Flags, CharT> + action_parser_t; + return action_parser_t(p, actor); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// predefined escape_char_parser objects +// +// These objects should be used for generating correct escaped character +// parsers. +// +/////////////////////////////////////////////////////////////////////////////// +const escape_char_parser<lex_escapes> lex_escape_ch_p = + escape_char_parser<lex_escapes>(); + +const escape_char_parser<c_escapes> c_escape_ch_p = + escape_char_parser<c_escapes>(); + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif diff --git a/boost/spirit/home/classic/utility/escape_char_fwd.hpp b/boost/spirit/home/classic/utility/escape_char_fwd.hpp new file mode 100644 index 0000000000..1485367164 --- /dev/null +++ b/boost/spirit/home/classic/utility/escape_char_fwd.hpp @@ -0,0 +1,30 @@ +/*============================================================================= + Copyright (c) 2006 Tobias Schwinger + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_ESCAPE_CHAR_FWD_HPP) +#define BOOST_SPIRIT_ESCAPE_CHAR_FWD_HPP + +#include <boost/spirit/home/classic/namespace.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + template <unsigned long Flags, typename CharT = char> + struct escape_char_parser; + + template < + class ParserT, typename ActionT, + unsigned long Flags, typename CharT = char> + struct escape_char_action; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + diff --git a/boost/spirit/home/classic/utility/flush_multi_pass.hpp b/boost/spirit/home/classic/utility/flush_multi_pass.hpp new file mode 100644 index 0000000000..ad69f4fefb --- /dev/null +++ b/boost/spirit/home/classic/utility/flush_multi_pass.hpp @@ -0,0 +1,77 @@ +/*============================================================================= + 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_FLUSH_MULTI_PASS_HPP +#define BOOST_SPIRIT_FLUSH_MULTI_PASS_HPP + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core.hpp> +#include <boost/spirit/home/classic/iterator/multi_pass.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + namespace impl { + + template <typename T> + void flush_iterator(T &) {} + + template <typename T1, typename T2, typename T3, typename T4> + void flush_iterator(BOOST_SPIRIT_CLASSIC_NS::multi_pass< + T1, T2, T3, T4, BOOST_SPIRIT_CLASSIC_NS::multi_pass_policies::std_deque> &i) + { + i.clear_queue(); + } + + } // namespace impl + + /////////////////////////////////////////////////////////////////////////// + // + // flush_multi_pass_parser + // + // The flush_multi_pass_parser flushes an underlying + // multi_pass_iterator during the normal parsing process. This may + // be used at certain points during the parsing process, when it is + // clear, that no backtracking is needed anymore and the input + // gathered so far may be discarded. + // + /////////////////////////////////////////////////////////////////////////// + class flush_multi_pass_parser + : public parser<flush_multi_pass_parser> + { + public: + typedef flush_multi_pass_parser this_t; + + template <typename ScannerT> + typename parser_result<this_t, ScannerT>::type + parse(ScannerT const& scan) const + { + impl::flush_iterator(scan.first); + return scan.empty_match(); + } + }; + + /////////////////////////////////////////////////////////////////////////// + // + // predefined flush_multi_pass_p object + // + // This object should may used to flush a multi_pass_iterator along + // the way during the normal parsing process. + // + /////////////////////////////////////////////////////////////////////////// + + flush_multi_pass_parser const + flush_multi_pass_p = flush_multi_pass_parser(); + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif // BOOST_SPIRIT_FLUSH_MULTI_PASS_HPP diff --git a/boost/spirit/home/classic/utility/functor_parser.hpp b/boost/spirit/home/classic/utility/functor_parser.hpp new file mode 100644 index 0000000000..ac53751bcc --- /dev/null +++ b/boost/spirit/home/classic/utility/functor_parser.hpp @@ -0,0 +1,71 @@ +/*============================================================================= + Copyright (c) 2002-2003 Joel de Guzman + Copyright (c) 2002-2003 Juan Carlos Arevalo-Baeza + 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_FUNCTOR_PARSER_HPP +#define BOOST_SPIRIT_FUNCTOR_PARSER_HPP + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // functor_parser class + // + // Once a functor parser has been defined, you can build a real + // parser from it by passing it to this class as the template + // parameter. + // + /////////////////////////////////////////////////////////////////////////// + template < class FunctorT > + struct functor_parser : public parser<functor_parser<FunctorT> > + { + FunctorT functor; + + functor_parser(): functor() {} + functor_parser(FunctorT const& functor_): functor(functor_) {} + + typedef typename FunctorT::result_t functor_result_t; + typedef functor_parser<FunctorT> self_t; + + template <typename ScannerT> + struct result + { + typedef typename match_result<ScannerT, functor_result_t>::type + type; + }; + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef typename parser_result<self_t, ScannerT>::type result_t; + typedef typename ScannerT::value_t value_t; + typedef typename ScannerT::iterator_t iterator_t; + + iterator_t const s(scan.first); + functor_result_t functor_result; + std::ptrdiff_t len = functor(scan, functor_result); + + if (len < 0) + return scan.no_match(); + else + return scan.create_match(std::size_t(len), functor_result, s, scan.first); + } + }; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif diff --git a/boost/spirit/home/classic/utility/grammar_def.hpp b/boost/spirit/home/classic/utility/grammar_def.hpp new file mode 100644 index 0000000000..6ddfcab647 --- /dev/null +++ b/boost/spirit/home/classic/utility/grammar_def.hpp @@ -0,0 +1,307 @@ +/*============================================================================= + Copyright (c) 2003 Hartmut Kaiser + Copyright (c) 2003 Joel de Guzman + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_GRAMMAR_DEF_HPP) +#define BOOST_SPIRIT_GRAMMAR_DEF_HPP + +#include <boost/mpl/if.hpp> +#include <boost/mpl/eval_if.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/preprocessor/arithmetic/inc.hpp> +#include <boost/preprocessor/arithmetic/dec.hpp> +#include <boost/preprocessor/enum.hpp> +#include <boost/preprocessor/enum_params.hpp> +#include <boost/preprocessor/repeat.hpp> +#include <boost/preprocessor/repeat_from_to.hpp> +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/phoenix/tuples.hpp> +#include <boost/spirit/home/classic/core/assert.hpp> +#include <boost/spirit/home/classic/utility/grammar_def_fwd.hpp> + +/////////////////////////////////////////////////////////////////////////////// +// +// Spirit predefined maximum grammar start parser limit. This limit defines +// the maximum number of of possible different parsers exposed from a +// particular grammar. This number defaults to 3. +// The actual maximum is rounded up in multiples of 3. Thus, if this value +// is 4, the actual limit is 6. The ultimate maximum limit in this +// implementation is 15. +// +// It should NOT be greater than PHOENIX_LIMIT! +// +/////////////////////////////////////////////////////////////////////////////// +#if !defined(BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT) +#define BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT PHOENIX_LIMIT +#endif + +/////////////////////////////////////////////////////////////////////////////// +// +// ensure BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT <= PHOENIX_LIMIT and +// BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT <= 15 and +// BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT > 0 +// +/////////////////////////////////////////////////////////////////////////////// +BOOST_STATIC_ASSERT(BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT <= PHOENIX_LIMIT); +BOOST_STATIC_ASSERT(BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT <= 15); +BOOST_STATIC_ASSERT(BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT > 0); + +////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +struct same {}; + +/////////////////////////////////////////////////////////////////////////////// +namespace impl { + + /////////////////////////////////////////////////////////////////////////// + // + // The make_const_pointer meta function allows to generate a T const* + // needed to store the pointer to a given start parser from a grammar. + // + /////////////////////////////////////////////////////////////////////////// + template <typename T0, typename T = T0> + struct make_const_pointer { + + private: + // T0 shouldn't be of type 'same' + BOOST_STATIC_ASSERT((!boost::is_same<T0, same>::value)); + + typedef typename boost::mpl::if_c< + boost::is_same<T, same>::value, + T0 const *, + T const * + >::type + ptr_type; + + public: + // If the type in question is phoenix::nil_t, then the returned type + // is still phoenix::nil_t, otherwise a constant pointer type to the + // inspected type is returned. + typedef typename boost::mpl::if_c< + boost::is_same<T, ::phoenix::nil_t>::value, + ::phoenix::nil_t, + ptr_type + >::type + type; + }; + + /////////////////////////////////////////////////////////////////////////// + template <int N, typename ElementT> + struct assign_zero_to_tuple_member { + + template <typename TupleT> + static void do_(TupleT &t) { t[::phoenix::tuple_index<N>()] = 0; } + }; + + template <int N> + struct assign_zero_to_tuple_member<N, ::phoenix::nil_t> { + + template <typename TupleT> + static void do_(TupleT& /*t*/) {} + }; + + struct phoenix_nil_type { + + typedef ::phoenix::nil_t type; + }; + + template <int N> + struct init_tuple_member { + + template <typename TupleT> + static void + do_(TupleT &t) + { + typedef typename boost::mpl::eval_if_c< + (N < TupleT::length), + ::phoenix::tuple_element<N, TupleT>, + phoenix_nil_type + >::type + element_type; + + assign_zero_to_tuple_member<N, element_type>::do_(t); + } + }; + +/////////////////////////////////////////////////////////////////////////////// +} // namespace impl + +/////////////////////////////////////////////////////////////////////////////// +// +// grammar_def class +// +// This class may be used as a base class for the embedded definition +// class inside the grammar<> derived user grammar. +// It exposes the two functions needed for start rule access: +// +// rule<> const &start() const; +// +// and +// +// template <int N> +// rule<> const *get_start_parser() const; +// +// Additionally it exposes a set o 'start_parsers' functions, which are to +// be called by the user to define the parsers to use as start parsers +// of the given grammar. +// +/////////////////////////////////////////////////////////////////////////////// +template < + typename T, + BOOST_PP_ENUM_PARAMS( + BOOST_PP_DEC(BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT_A), typename T) +> +class grammar_def { + +private: + /////////////////////////////////////////////////////////////////////////// + // + // This generates the full tuple type from the given template parameters + // T, T0, ... + // + // typedef ::phoenix::tuple< + // typename impl::make_const_pointer<T>::type, + // typename impl::make_const_pointer<T, T0>::type, + // ... + // > tuple_t; + // + /////////////////////////////////////////////////////////////////////////// + #define BOOST_SPIRIT_GRAMMARDEF_TUPLE_PARAM(z, N, _) \ + typename impl::make_const_pointer<T, BOOST_PP_CAT(T, N)>::type \ + /**/ + + typedef ::phoenix::tuple< + typename impl::make_const_pointer<T>::type, + BOOST_PP_ENUM( + BOOST_PP_DEC(BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT_A), + BOOST_SPIRIT_GRAMMARDEF_TUPLE_PARAM, + _ + ) + > tuple_t; + + #undef BOOST_SPIRIT_GRAMMARDEF_TUPLE_PARAM + /////////////////////////////////////////////////////////////////////////// + +protected: + /////////////////////////////////////////////////////////////////////////// + // + // This generates a sequence of 'start_parsers' functions with increasing + // number of arguments, which allow to initialize the tuple members with + // the pointers to the start parsers of the grammar: + // + // template <typename TC0, ...> + // void start_parsers (TC0 const &t0, ...) + // { + // using ::phoenix::tuple_index_names::_1; + // t[_1] = &t0; + // ... + // } + // + // where a TC0 const* must be convertible to a T0 const* + // + /////////////////////////////////////////////////////////////////////////// + #define BOOST_SPIRIT_GRAMMARDEF_ENUM_PARAMS(z, N, _) \ + BOOST_PP_CAT(TC, N) const &BOOST_PP_CAT(t, N) \ + /**/ + #define BOOST_SPIRIT_GRAMMARDEF_ENUM_ASSIGN(z, N, _) \ + using ::phoenix::tuple_index_names::BOOST_PP_CAT(_, BOOST_PP_INC(N)); \ + t[BOOST_PP_CAT(_, BOOST_PP_INC(N))] = &BOOST_PP_CAT(t, N); \ + /**/ + #define BOOST_SPIRIT_GRAMMARDEF_ENUM_START(z, N, _) \ + template <BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), typename TC)> \ + void \ + start_parsers(BOOST_PP_ENUM_ ## z(BOOST_PP_INC(N), \ + BOOST_SPIRIT_GRAMMARDEF_ENUM_PARAMS, _) ) \ + { \ + BOOST_PP_REPEAT_ ## z(BOOST_PP_INC(N), \ + BOOST_SPIRIT_GRAMMARDEF_ENUM_ASSIGN, _) \ + } \ + /**/ + + BOOST_PP_REPEAT( + BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT_A, + BOOST_SPIRIT_GRAMMARDEF_ENUM_START, _) + + #undef BOOST_SPIRIT_GRAMMARDEF_ENUM_START + #undef BOOST_SPIRIT_GRAMMARDEF_ENUM_ASSIGN + #undef BOOST_SPIRIT_GRAMMARDEF_ENUM_PARAMS + /////////////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////////////// + // + // This generates some initialization code, which allows to initialize all + // used tuple members to 0 (zero): + // + // t[_1] = 0; + // impl::init_tuple_member<1>::do_(t); + // ... + // + /////////////////////////////////////////////////////////////////////////// + #define BOOST_SPIRIT_GRAMMARDEF_ENUM_INIT(z, N, _) \ + impl::init_tuple_member<N>::do_(t); \ + /**/ + + grammar_def() + { + using ::phoenix::tuple_index_names::_1; + t[_1] = 0; + BOOST_PP_REPEAT_FROM_TO( + 1, BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT_A, + BOOST_SPIRIT_GRAMMARDEF_ENUM_INIT, _) + } + + #undef BOOST_SPIRIT_GRAMMARDEF_ENUM_INIT + /////////////////////////////////////////////////////////////////////////// + +public: + T const & + start() const + { + // If the following assertion is fired, you have probably forgot to call + // the start_parser() function from inside the constructor of your + // embedded definition class to initialize the start parsers to be exposed + // from your grammar. + using ::phoenix::tuple_index_names::_1; + BOOST_SPIRIT_ASSERT(0 != t[_1]); + return *t[_1]; + } + + template <int N> + typename ::phoenix::tuple_element<N, tuple_t>::crtype + get_start_parser() const + { + // If the following expression yields a compiler error, you have probably + // tried to access a start rule, which isn't exposed as such from your + // grammar. + BOOST_STATIC_ASSERT(N > 0 && N < tuple_t::length); + + // If the following assertion is fired, you have probably forgot to call + // the start_parser() function from inside the constructor of your + // embedded definition class to initialize the start parsers to be exposed + // from your grammar. + // Another reason may be, that there is a count mismatch between + // the number of template parameters to the grammar_def<> class and the + // number of parameters used while calling start_parsers(). + BOOST_SPIRIT_ASSERT(0 != t[::phoenix::tuple_index<N>()]); + + return t[::phoenix::tuple_index<N>()]; + } + +private: + tuple_t t; +}; + +#undef BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT_A + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif // BOOST_SPIRIT_GRAMMAR_DEF_HPP diff --git a/boost/spirit/home/classic/utility/grammar_def_fwd.hpp b/boost/spirit/home/classic/utility/grammar_def_fwd.hpp new file mode 100644 index 0000000000..cf9e3851c6 --- /dev/null +++ b/boost/spirit/home/classic/utility/grammar_def_fwd.hpp @@ -0,0 +1,52 @@ +/*============================================================================= + Copyright (c) 2006 Tobias Schwinger + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_GRAMMAR_DEF_FWD_HPP) +#define BOOST_SPIRIT_GRAMMAR_DEF_FWD_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/phoenix/tuples.hpp> + +#include <boost/preprocessor/repetition/enum_binary_params.hpp> +#include <boost/preprocessor/facilities/intercept.hpp> + +#if !defined(BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT) +#define BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT PHOENIX_LIMIT +#endif + +// Calculate an integer rounded up to the nearest integer dividable by 3 +#if BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT > 12 +#define BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT_A 15 +#elif BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT > 9 +#define BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT_A 12 +#elif BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT > 6 +#define BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT_A 9 +#elif BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT > 3 +#define BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT_A 6 +#else +#define BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT_A 3 +#endif + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + template < + typename T, + BOOST_PP_ENUM_BINARY_PARAMS( + BOOST_PP_DEC(BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT_A), + typename T, = ::phoenix::nil_t BOOST_PP_INTERCEPT + ) + > + class grammar_def; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + diff --git a/boost/spirit/home/classic/utility/impl/chset.ipp b/boost/spirit/home/classic/utility/impl/chset.ipp new file mode 100644 index 0000000000..3017035106 --- /dev/null +++ b/boost/spirit/home/classic/utility/impl/chset.ipp @@ -0,0 +1,366 @@ +/*============================================================================= + 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_SPIRIT_CHSET_IPP +#define BOOST_SPIRIT_CHSET_IPP + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/limits.hpp> +#include <boost/spirit/home/classic/utility/chset.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// +// chset class +// +/////////////////////////////////////////////////////////////////////////////// +namespace utility { namespace impl { + template <typename CharT> + inline void + detach(boost::shared_ptr<basic_chset<CharT> >& ptr) + { + if (!ptr.unique()) + ptr = boost::shared_ptr<basic_chset<CharT> > + (new basic_chset<CharT>(*ptr)); + } + + template <typename CharT> + inline void + detach_clear(boost::shared_ptr<basic_chset<CharT> >& ptr) + { + if (ptr.unique()) + ptr->clear(); + else + ptr.reset(new basic_chset<CharT>()); + } + + template <typename CharT, typename CharT2> + void construct_chset(boost::shared_ptr<basic_chset<CharT> >& ptr, + CharT2 const* definition) + { + CharT2 ch = *definition++; + while (ch) + { + CharT2 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; + } + } + + ////////////////////////////////// + +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) + + template <typename CharT, typename FakeT> + void chset_negated_set(boost::shared_ptr<basic_chset<CharT> > &ptr, chlit<CharT> const &ch, + FakeT) + { + if(ch.ch != (std::numeric_limits<CharT>::min)()) { + ptr->set((std::numeric_limits<CharT>::min)(), ch.ch - 1); + } + if(ch.ch != (std::numeric_limits<CharT>::max)()) { + ptr->set(ch.ch + 1, (std::numeric_limits<CharT>::max)()); + } + } + + template <typename CharT, typename FakeT> + void chset_negated_set(boost::shared_ptr<basic_chset<CharT> > &ptr, + spirit::range<CharT> const &rng, FakeT) + { + if(rng.first != (std::numeric_limits<CharT>::min)()) { + ptr->set((std::numeric_limits<CharT>::min)(), rng.first - 1); + } + if(rng.last != (std::numeric_limits<CharT>::max)()) { + ptr->set(rng.last + 1, (std::numeric_limits<CharT>::max)()); + } + } + +#endif // BOOST_WORKAROUND(BOOST_MSVC, < 1300) + +////////////////////////////////// + +}} // namespace utility::impl + +template <typename CharT> +inline chset<CharT>::chset() +: ptr(new basic_chset<CharT>()) {} + +template <typename CharT> +inline chset<CharT>::chset(chset const& arg_) +: ptr(new basic_chset<CharT>(*arg_.ptr)) {} + +template <typename CharT> +inline chset<CharT>::chset(CharT arg_) +: ptr(new basic_chset<CharT>()) +{ ptr->set(arg_); } + +template <typename CharT> +inline chset<CharT>::chset(anychar_parser /*arg*/) +: ptr(new basic_chset<CharT>()) +{ + ptr->set( + (std::numeric_limits<CharT>::min)(), + (std::numeric_limits<CharT>::max)() + ); +} + +template <typename CharT> +inline chset<CharT>::chset(nothing_parser arg_) +: ptr(new basic_chset<CharT>()) {} + +template <typename CharT> +inline chset<CharT>::chset(chlit<CharT> const& arg_) +: ptr(new basic_chset<CharT>()) +{ ptr->set(arg_.ch); } + +template <typename CharT> +inline chset<CharT>::chset(range<CharT> const& arg_) +: ptr(new basic_chset<CharT>()) +{ ptr->set(arg_.first, arg_.last); } + +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) + +template <typename CharT> +inline chset<CharT>::chset(negated_char_parser<chlit<CharT> > const& arg_) +: ptr(new basic_chset<CharT>()) +{ + set(arg_); +} + +template <typename CharT> +inline chset<CharT>::chset(negated_char_parser<range<CharT> > const& arg_) +: ptr(new basic_chset<CharT>()) +{ + set(arg_); +} + +#endif // !BOOST_WORKAROUND(BOOST_MSVC, < 1300) + +template <typename CharT> +inline chset<CharT>::~chset() {} + +template <typename CharT> +inline chset<CharT>& +chset<CharT>::operator=(chset const& rhs) +{ + ptr = rhs.ptr; + return *this; +} + +template <typename CharT> +inline chset<CharT>& +chset<CharT>::operator=(CharT rhs) +{ + utility::impl::detach_clear(ptr); + ptr->set(rhs); + return *this; +} + +template <typename CharT> +inline chset<CharT>& +chset<CharT>::operator=(anychar_parser rhs) +{ + utility::impl::detach_clear(ptr); + ptr->set( + (std::numeric_limits<CharT>::min)(), + (std::numeric_limits<CharT>::max)() + ); + return *this; +} + +template <typename CharT> +inline chset<CharT>& +chset<CharT>::operator=(nothing_parser rhs) +{ + utility::impl::detach_clear(ptr); + return *this; +} + +template <typename CharT> +inline chset<CharT>& +chset<CharT>::operator=(chlit<CharT> const& rhs) +{ + utility::impl::detach_clear(ptr); + ptr->set(rhs.ch); + return *this; +} + +template <typename CharT> +inline chset<CharT>& +chset<CharT>::operator=(range<CharT> const& rhs) +{ + utility::impl::detach_clear(ptr); + ptr->set(rhs.first, rhs.last); + return *this; +} + +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) + +template <typename CharT> +inline chset<CharT>& +chset<CharT>::operator=(negated_char_parser<chlit<CharT> > const& rhs) +{ + utility::impl::detach_clear(ptr); + set(rhs); + return *this; +} + +template <typename CharT> +inline chset<CharT>& +chset<CharT>::operator=(negated_char_parser<range<CharT> > const& rhs) +{ + utility::impl::detach_clear(ptr); + set(rhs); + return *this; +} + +#endif // !BOOST_WORKAROUND(BOOST_MSVC, < 1300) + +template <typename CharT> +inline void +chset<CharT>::set(range<CharT> const& arg_) +{ + utility::impl::detach(ptr); + ptr->set(arg_.first, arg_.last); +} + +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) + +template <typename CharT> +inline void +chset<CharT>::set(negated_char_parser<chlit<CharT> > const& arg_) +{ + utility::impl::detach(ptr); + + if(arg_.positive.ch != (std::numeric_limits<CharT>::min)()) { + ptr->set((std::numeric_limits<CharT>::min)(), arg_.positive.ch - 1); + } + if(arg_.positive.ch != (std::numeric_limits<CharT>::max)()) { + ptr->set(arg_.positive.ch + 1, (std::numeric_limits<CharT>::max)()); + } +} + +template <typename CharT> +inline void +chset<CharT>::set(negated_char_parser<range<CharT> > const& arg_) +{ + utility::impl::detach(ptr); + + if(arg_.positive.first != (std::numeric_limits<CharT>::min)()) { + ptr->set((std::numeric_limits<CharT>::min)(), arg_.positive.first - 1); + } + if(arg_.positive.last != (std::numeric_limits<CharT>::max)()) { + ptr->set(arg_.positive.last + 1, (std::numeric_limits<CharT>::max)()); + } +} + +#endif // !BOOST_WORKAROUND(BOOST_MSVC, < 1300) + +template <typename CharT> +inline void +chset<CharT>::clear(range<CharT> const& arg_) +{ + utility::impl::detach(ptr); + ptr->clear(arg_.first, arg_.last); +} + +template <typename CharT> +inline void +chset<CharT>::clear(negated_char_parser<range<CharT> > const& arg_) +{ + utility::impl::detach(ptr); + + if(arg_.positive.first != (std::numeric_limits<CharT>::min)()) { + ptr->clear((std::numeric_limits<CharT>::min)(), arg_.positive.first - 1); + } + if(arg_.positive.last != (std::numeric_limits<CharT>::max)()) { + ptr->clear(arg_.positive.last + 1, (std::numeric_limits<CharT>::max)()); + } +} + +template <typename CharT> +inline bool +chset<CharT>::test(CharT ch) const +{ return ptr->test(ch); } + +template <typename CharT> +inline chset<CharT>& +chset<CharT>::inverse() +{ + utility::impl::detach(ptr); + ptr->inverse(); + return *this; +} + +template <typename CharT> +inline void +chset<CharT>::swap(chset& x) +{ ptr.swap(x.ptr); } + +template <typename CharT> +inline chset<CharT>& +chset<CharT>::operator|=(chset const& x) +{ + utility::impl::detach(ptr); + *ptr |= *x.ptr; + return *this; +} + +template <typename CharT> +inline chset<CharT>& +chset<CharT>::operator&=(chset const& x) +{ + utility::impl::detach(ptr); + *ptr &= *x.ptr; + return *this; +} + +template <typename CharT> +inline chset<CharT>& +chset<CharT>::operator-=(chset const& x) +{ + utility::impl::detach(ptr); + *ptr -= *x.ptr; + return *this; +} + +template <typename CharT> +inline chset<CharT>& +chset<CharT>::operator^=(chset const& x) +{ + utility::impl::detach(ptr); + *ptr ^= *x.ptr; + return *this; +} + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#endif + diff --git a/boost/spirit/home/classic/utility/impl/chset/basic_chset.hpp b/boost/spirit/home/classic/utility/impl/chset/basic_chset.hpp new file mode 100644 index 0000000000..ace650166f --- /dev/null +++ b/boost/spirit/home/classic/utility/impl/chset/basic_chset.hpp @@ -0,0 +1,107 @@ +/*============================================================================= + Copyright (c) 2001-2003 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_HPP +#define BOOST_SPIRIT_BASIC_CHSET_HPP + +/////////////////////////////////////////////////////////////////////////////// +#include <bitset> +#include <climits> +#include <boost/spirit/home/classic/utility/impl/chset/range_run.hpp> +#include <boost/spirit/home/classic/namespace.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // basic_chset: basic character set implementation using range_run + // + /////////////////////////////////////////////////////////////////////////// + template <typename CharT> + class basic_chset + { + public: + basic_chset(); + basic_chset(basic_chset const& arg_); + + bool test(CharT v) const; + void set(CharT from, CharT to); + void set(CharT c); + void clear(CharT from, CharT to); + void clear(CharT c); + void clear(); + + 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: utility::impl::range_run<CharT> rr; + }; + + #if (CHAR_BIT == 8) + + /////////////////////////////////////////////////////////////////////////// + // + // basic_chset: specializations for 8 bit chars using std::bitset + // + /////////////////////////////////////////////////////////////////////////// + template <typename CharT> + class basic_chset_8bit { + + public: + basic_chset_8bit(); + basic_chset_8bit(basic_chset_8bit const& arg_); + + bool test(CharT v) const; + void set(CharT from, CharT to); + void set(CharT c); + void clear(CharT from, CharT to); + void clear(CharT c); + void clear(); + + 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); + + private: std::bitset<256> bset; + }; + + ///////////////////////////////// + template <> + class basic_chset<char> + : public basic_chset_8bit<char> {}; + + ///////////////////////////////// + template <> + class basic_chset<signed char> + : public basic_chset_8bit<signed char> {}; + + ///////////////////////////////// + template <> + class basic_chset<unsigned char> + : public basic_chset_8bit<unsigned char> {}; + +#endif + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + +#include <boost/spirit/home/classic/utility/impl/chset/basic_chset.ipp> diff --git a/boost/spirit/home/classic/utility/impl/chset/basic_chset.ipp b/boost/spirit/home/classic/utility/impl/chset/basic_chset.ipp new file mode 100644 index 0000000000..e7d9272345 --- /dev/null +++ b/boost/spirit/home/classic/utility/impl/chset/basic_chset.ipp @@ -0,0 +1,246 @@ +/*============================================================================= + 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_SPIRIT_BASIC_CHSET_IPP +#define BOOST_SPIRIT_BASIC_CHSET_IPP + +/////////////////////////////////////////////////////////////////////////////// +#include <bitset> +#include <boost/spirit/home/classic/utility/impl/chset/basic_chset.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// +// basic_chset: character set implementation +// +/////////////////////////////////////////////////////////////////////////////// +template <typename CharT> +inline basic_chset<CharT>::basic_chset() {} + +////////////////////////////////// +template <typename CharT> +inline basic_chset<CharT>::basic_chset(basic_chset const& arg_) +: rr(arg_.rr) {} + +////////////////////////////////// +template <typename CharT> +inline bool +basic_chset<CharT>::test(CharT v) const +{ return rr.test(v); } + +////////////////////////////////// +template <typename CharT> +inline void +basic_chset<CharT>::set(CharT from, CharT to) +{ rr.set(utility::impl::range<CharT>(from, to)); } + +////////////////////////////////// +template <typename CharT> +inline void +basic_chset<CharT>::set(CharT c) +{ rr.set(utility::impl::range<CharT>(c, c)); } + +////////////////////////////////// +template <typename CharT> +inline void +basic_chset<CharT>::clear(CharT from, CharT to) +{ rr.clear(utility::impl::range<CharT>(from, to)); } + +////////////////////////////////// +template <typename CharT> +inline void +basic_chset<CharT>::clear() +{ rr.clear(); } + +///////////////////////////////// +template <typename CharT> +inline void +basic_chset<CharT>::inverse() +{ + basic_chset inv; + inv.set( + (std::numeric_limits<CharT>::min)(), + (std::numeric_limits<CharT>::max)() + ); + inv -= *this; + swap(inv); +} + +///////////////////////////////// +template <typename CharT> +inline void +basic_chset<CharT>::swap(basic_chset& x) +{ rr.swap(x.rr); } + +///////////////////////////////// +template <typename CharT> +inline basic_chset<CharT>& +basic_chset<CharT>::operator|=(basic_chset<CharT> const& x) +{ + typedef typename utility::impl::range_run<CharT>::const_iterator const_iterator; + for (const_iterator iter = x.rr.begin(); iter != x.rr.end(); ++iter) + rr.set(*iter); + return *this; +} + +///////////////////////////////// +template <typename CharT> +inline basic_chset<CharT>& +basic_chset<CharT>::operator&=(basic_chset<CharT> const& x) +{ + basic_chset inv; + inv.set( + (std::numeric_limits<CharT>::min)(), + (std::numeric_limits<CharT>::max)() + ); + inv -= x; + *this -= inv; + return *this; +} + +///////////////////////////////// +template <typename CharT> +inline basic_chset<CharT>& +basic_chset<CharT>::operator-=(basic_chset<CharT> const& x) +{ + typedef typename utility::impl::range_run<CharT>::const_iterator const_iterator; + for (const_iterator iter = x.rr.begin(); iter != x.rr.end(); ++iter) + rr.clear(*iter); + return *this; +} + +///////////////////////////////// +template <typename CharT> +inline basic_chset<CharT>& +basic_chset<CharT>::operator^=(basic_chset<CharT> const& x) +{ + basic_chset bma = x; + bma -= *this; + *this -= x; + *this |= bma; + return *this; +} + +#if (CHAR_BIT == 8) + +/////////////////////////////////////////////////////////////////////////////// +// +// basic_chset: specializations for 8 bit chars using std::bitset +// +/////////////////////////////////////////////////////////////////////////////// +template <typename CharT> +inline basic_chset_8bit<CharT>::basic_chset_8bit() {} + +///////////////////////////////// +template <typename CharT> +inline basic_chset_8bit<CharT>::basic_chset_8bit(basic_chset_8bit const& arg_) +: bset(arg_.bset) {} + +///////////////////////////////// +template <typename CharT> +inline bool +basic_chset_8bit<CharT>::test(CharT v) const +{ return bset.test((unsigned char)v); } + +///////////////////////////////// +template <typename CharT> +inline void +basic_chset_8bit<CharT>::set(CharT from, CharT to) +{ + for (int i = from; i <= to; ++i) + bset.set((unsigned char)i); +} + +///////////////////////////////// +template <typename CharT> +inline void +basic_chset_8bit<CharT>::set(CharT c) +{ bset.set((unsigned char)c); } + +///////////////////////////////// +template <typename CharT> +inline void +basic_chset_8bit<CharT>::clear(CharT from, CharT to) +{ + for (int i = from; i <= to; ++i) + bset.reset((unsigned char)i); +} + +///////////////////////////////// +template <typename CharT> +inline void +basic_chset_8bit<CharT>::clear(CharT c) +{ bset.reset((unsigned char)c); } + +///////////////////////////////// +template <typename CharT> +inline void +basic_chset_8bit<CharT>::clear() +{ bset.reset(); } + +///////////////////////////////// +template <typename CharT> +inline void +basic_chset_8bit<CharT>::inverse() +{ bset.flip(); } + +///////////////////////////////// +template <typename CharT> +inline void +basic_chset_8bit<CharT>::swap(basic_chset_8bit& x) +{ std::swap(bset, x.bset); } + +///////////////////////////////// +template <typename CharT> +inline basic_chset_8bit<CharT>& +basic_chset_8bit<CharT>::operator|=(basic_chset_8bit const& x) +{ + bset |= x.bset; + return *this; +} + +///////////////////////////////// +template <typename CharT> +inline basic_chset_8bit<CharT>& +basic_chset_8bit<CharT>::operator&=(basic_chset_8bit const& x) +{ + bset &= x.bset; + return *this; +} + +///////////////////////////////// +template <typename CharT> +inline basic_chset_8bit<CharT>& +basic_chset_8bit<CharT>::operator-=(basic_chset_8bit const& x) +{ + bset &= ~x.bset; + return *this; +} + +///////////////////////////////// +template <typename CharT> +inline basic_chset_8bit<CharT>& +basic_chset_8bit<CharT>::operator^=(basic_chset_8bit const& x) +{ + bset ^= x.bset; + return *this; +} + +#endif + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#endif + diff --git a/boost/spirit/home/classic/utility/impl/chset/range_run.hpp b/boost/spirit/home/classic/utility/impl/chset/range_run.hpp new file mode 100644 index 0000000000..579bcaec70 --- /dev/null +++ b/boost/spirit/home/classic/utility/impl/chset/range_run.hpp @@ -0,0 +1,127 @@ +/*============================================================================= + Copyright (c) 2001-2003 Joel de Guzman + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#ifndef BOOST_SPIRIT_RANGE_RUN_HPP +#define BOOST_SPIRIT_RANGE_RUN_HPP + +/////////////////////////////////////////////////////////////////////////////// +#include <vector> + +#include <boost/spirit/home/classic/namespace.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +namespace utility { namespace impl { + + /////////////////////////////////////////////////////////////////////////// + // + // 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 BOOST_SPIRIT_CLASSIC_NS::range } + // + /////////////////////////////////////////////////////////////////////////// + template <typename CharT> + struct range { + + range(CharT first, CharT last); + + bool is_valid() const; + bool includes(CharT v) const; + bool includes(range const& r) const; + bool overlaps(range const& r) const; + void merge(range const& r); + + CharT first; + CharT last; + }; + + ////////////////////////////////// + template <typename CharT> + struct range_char_compare { + + bool operator()(range<CharT> const& x, const CharT y) const + { return x.first < y; } + + bool operator()(const CharT x, range<CharT> const& y) const + { return x < y.first; } + + // This additional operator is required for the checked STL shipped + // with VC8 testing the ordering of the iterators passed to the + // std::lower_bound algo this range_char_compare<> predicate is passed + // to. + bool operator()(range<CharT> const& x, range<CharT> const& y) const + { return x.first < y.first; } + }; + + ////////////////////////////////// + template <typename CharT> + struct range_compare { + + bool operator()(range<CharT> const& x, range<CharT> 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 CharT> + class range_run { + + public: + + typedef range<CharT> range_t; + typedef std::vector<range_t> run_t; + typedef typename run_t::iterator iterator; + typedef typename run_t::const_iterator const_iterator; + + void swap(range_run& rr); + bool test(CharT v) const; + void set(range_t const& r); + void clear(range_t const& r); + void clear(); + + const_iterator begin() const; + const_iterator end() const; + + private: + + void merge(iterator iter, range_t const& r); + + run_t run; + }; + +}} + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS::utility::impl + +#endif + +#include <boost/spirit/home/classic/utility/impl/chset/range_run.ipp> diff --git a/boost/spirit/home/classic/utility/impl/chset/range_run.ipp b/boost/spirit/home/classic/utility/impl/chset/range_run.ipp new file mode 100644 index 0000000000..ede15673fc --- /dev/null +++ b/boost/spirit/home/classic/utility/impl/chset/range_run.ipp @@ -0,0 +1,218 @@ +/*============================================================================= + 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_SPIRIT_RANGE_RUN_IPP +#define BOOST_SPIRIT_RANGE_RUN_IPP + +/////////////////////////////////////////////////////////////////////////////// +#include <algorithm> // for std::lower_bound +#include <boost/spirit/home/classic/core/assert.hpp> // for BOOST_SPIRIT_ASSERT +#include <boost/spirit/home/classic/utility/impl/chset/range_run.hpp> +#include <boost/spirit/home/classic/debug.hpp> +#include <boost/limits.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + namespace utility { namespace impl { + + /////////////////////////////////////////////////////////////////////// + // + // range class implementation + // + /////////////////////////////////////////////////////////////////////// + template <typename CharT> + inline range<CharT>::range(CharT first_, CharT last_) + : first(first_), last(last_) {} + + ////////////////////////////////// + template <typename CharT> + inline bool + range<CharT>::is_valid() const + { return first <= last; } + + ////////////////////////////////// + template <typename CharT> + inline bool + range<CharT>::includes(range const& r) const + { return (first <= r.first) && (last >= r.last); } + + ////////////////////////////////// + template <typename CharT> + inline bool + range<CharT>::includes(CharT v) const + { return (first <= v) && (last >= v); } + + ////////////////////////////////// + template <typename CharT> + inline bool + range<CharT>::overlaps(range const& r) const + { + CharT decr_first = + first == (std::numeric_limits<CharT>::min)() ? first : first-1; + CharT incr_last = + last == (std::numeric_limits<CharT>::max)() ? last : last+1; + + return (decr_first <= r.last) && (incr_last >= r.first); + } + + ////////////////////////////////// + template <typename CharT> + inline void + range<CharT>::merge(range const& r) + { + first = (std::min)(first, r.first); + last = (std::max)(last, r.last); + } + + /////////////////////////////////////////////////////////////////////// + // + // range_run class implementation + // + /////////////////////////////////////////////////////////////////////// + template <typename CharT> + inline bool + range_run<CharT>::test(CharT v) const + { + if (!run.empty()) + { + const_iterator iter = + std::lower_bound( + run.begin(), run.end(), v, + range_char_compare<CharT>() + ); + + if (iter != run.end() && iter->includes(v)) + return true; + if (iter != run.begin()) + return (--iter)->includes(v); + } + return false; + } + + ////////////////////////////////// + template <typename CharT> + inline void + range_run<CharT>::swap(range_run& rr) + { run.swap(rr.run); } + + ////////////////////////////////// + template <typename CharT> + void + range_run<CharT>::merge(iterator iter, range<CharT> const& r) + { + iter->merge(r); + iterator i = iter + 1; + + while (i != run.end() && iter->overlaps(*i)) + iter->merge(*i++); + + run.erase(iter+1, i); + } + + ////////////////////////////////// + template <typename CharT> + void + range_run<CharT>::set(range<CharT> const& r) + { + BOOST_SPIRIT_ASSERT(r.is_valid()); + if (!run.empty()) + { + iterator iter = + std::lower_bound( + run.begin(), run.end(), r, + range_compare<CharT>() + ); + + if ((iter != run.end() && iter->includes(r)) || + ((iter != run.begin()) && (iter - 1)->includes(r))) + return; + + if (iter != run.begin() && (iter - 1)->overlaps(r)) + merge(--iter, r); + + else if (iter != run.end() && iter->overlaps(r)) + merge(iter, r); + + else + run.insert(iter, r); + } + else + { + run.push_back(r); + } + } + + ////////////////////////////////// + template <typename CharT> + void + range_run<CharT>::clear(range<CharT> const& r) + { + BOOST_SPIRIT_ASSERT(r.is_valid()); + if (!run.empty()) + { + iterator iter = + std::lower_bound( + run.begin(), run.end(), r, + range_compare<CharT>() + ); + + iterator left_iter; + + if ((iter != run.begin()) && + (left_iter = (iter - 1))->includes(r.first)) + { + if (left_iter->last > r.last) + { + CharT save_last = left_iter->last; + left_iter->last = r.first-1; + run.insert(iter, range<CharT>(r.last+1, save_last)); + return; + } + else + { + left_iter->last = r.first-1; + } + } + + iterator i = iter; + while (i != run.end() && r.includes(*i)) + i++; + if (i != run.end() && i->includes(r.last)) + i->first = r.last+1; + run.erase(iter, i); + } + } + + ////////////////////////////////// + template <typename CharT> + inline void + range_run<CharT>::clear() + { run.clear(); } + + ////////////////////////////////// + template <typename CharT> + inline typename range_run<CharT>::const_iterator + range_run<CharT>::begin() const + { return run.begin(); } + + ////////////////////////////////// + template <typename CharT> + inline typename range_run<CharT>::const_iterator + range_run<CharT>::end() const + { return run.end(); } + + }} // namespace utility::impl + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#endif diff --git a/boost/spirit/home/classic/utility/impl/chset_operators.ipp b/boost/spirit/home/classic/utility/impl/chset_operators.ipp new file mode 100644 index 0000000000..4319c9b2a8 --- /dev/null +++ b/boost/spirit/home/classic/utility/impl/chset_operators.ipp @@ -0,0 +1,666 @@ +/*============================================================================= + 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_SPIRIT_CHSET_OPERATORS_IPP +#define BOOST_SPIRIT_CHSET_OPERATORS_IPP + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/limits.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// +// chset free operators implementation +// +/////////////////////////////////////////////////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator|(chset<CharT> const& a, chset<CharT> const& b) +{ + return chset<CharT>(a) |= b; +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator-(chset<CharT> const& a, chset<CharT> const& b) +{ + return chset<CharT>(a) -= b; +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator~(chset<CharT> const& a) +{ + return chset<CharT>(a).inverse(); +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator&(chset<CharT> const& a, chset<CharT> const& b) +{ + return chset<CharT>(a) &= b; +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator^(chset<CharT> const& a, chset<CharT> const& b) +{ + return chset<CharT>(a) ^= b; +} + +/////////////////////////////////////////////////////////////////////////////// +// +// range <--> chset free operators implementation +// +/////////////////////////////////////////////////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator|(chset<CharT> const& a, range<CharT> const& b) +{ + chset<CharT> a_(a); + a_.set(b); + return a_; +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator&(chset<CharT> const& a, range<CharT> const& b) +{ + chset<CharT> a_(a); + if(b.first != (std::numeric_limits<CharT>::min)()) { + a_.clear(range<CharT>((std::numeric_limits<CharT>::min)(), b.first - 1)); + } + if(b.last != (std::numeric_limits<CharT>::max)()) { + a_.clear(range<CharT>(b.last + 1, (std::numeric_limits<CharT>::max)())); + } + return a_; +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator-(chset<CharT> const& a, range<CharT> const& b) +{ + chset<CharT> a_(a); + a_.clear(b); + return a_; +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator^(chset<CharT> const& a, range<CharT> const& b) +{ + return a ^ chset<CharT>(b); +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator|(range<CharT> const& a, chset<CharT> const& b) +{ + chset<CharT> b_(b); + b_.set(a); + return b_; +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator&(range<CharT> const& a, chset<CharT> const& b) +{ + chset<CharT> b_(b); + if(a.first != (std::numeric_limits<CharT>::min)()) { + b_.clear(range<CharT>((std::numeric_limits<CharT>::min)(), a.first - 1)); + } + if(a.last != (std::numeric_limits<CharT>::max)()) { + b_.clear(range<CharT>(a.last + 1, (std::numeric_limits<CharT>::max)())); + } + return b_; +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator-(range<CharT> const& a, chset<CharT> const& b) +{ + return chset<CharT>(a) - b; +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator^(range<CharT> const& a, chset<CharT> const& b) +{ + return chset<CharT>(a) ^ b; +} + +/////////////////////////////////////////////////////////////////////////////// +// +// literal primitives <--> chset free operators implementation +// +/////////////////////////////////////////////////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator|(chset<CharT> const& a, CharT b) +{ + return a | chset<CharT>(b); +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator&(chset<CharT> const& a, CharT b) +{ + return a & chset<CharT>(b); +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator-(chset<CharT> const& a, CharT b) +{ + return a - chset<CharT>(b); +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator^(chset<CharT> const& a, CharT b) +{ + return a ^ chset<CharT>(b); +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator|(CharT a, chset<CharT> const& b) +{ + return chset<CharT>(a) | b; +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator&(CharT a, chset<CharT> const& b) +{ + return chset<CharT>(a) & b; +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator-(CharT a, chset<CharT> const& b) +{ + return chset<CharT>(a) - b; +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator^(CharT a, chset<CharT> const& b) +{ + return chset<CharT>(a) ^ b; +} + +/////////////////////////////////////////////////////////////////////////////// +// +// chlit <--> chset free operators implementation +// +/////////////////////////////////////////////////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator|(chset<CharT> const& a, chlit<CharT> const& b) +{ + return a | chset<CharT>(b.ch); +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator&(chset<CharT> const& a, chlit<CharT> const& b) +{ + return a & chset<CharT>(b.ch); +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator-(chset<CharT> const& a, chlit<CharT> const& b) +{ + return a - chset<CharT>(b.ch); +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator^(chset<CharT> const& a, chlit<CharT> const& b) +{ + return a ^ chset<CharT>(b.ch); +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator|(chlit<CharT> const& a, chset<CharT> const& b) +{ + return chset<CharT>(a.ch) | b; +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator&(chlit<CharT> const& a, chset<CharT> const& b) +{ + return chset<CharT>(a.ch) & b; +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator-(chlit<CharT> const& a, chset<CharT> const& b) +{ + return chset<CharT>(a.ch) - b; +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator^(chlit<CharT> const& a, chset<CharT> const& b) +{ + return chset<CharT>(a.ch) ^ b; +} + +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) + +/////////////////////////////////////////////////////////////////////////////// +// +// negated_char_parser <--> chset free operators implementation +// +/////////////////////////////////////////////////////////////////////////////// +template <typename CharT, typename ParserT> +inline chset<CharT> +operator|(chset<CharT> const& a, negated_char_parser<ParserT> const& b) +{ + return a | chset<CharT>(b); +} + +////////////////////////////////// +template <typename CharT, typename ParserT> +inline chset<CharT> +operator&(chset<CharT> const& a, negated_char_parser<ParserT> const& b) +{ + return a & chset<CharT>(b); +} + +////////////////////////////////// +template <typename CharT, typename ParserT> +inline chset<CharT> +operator-(chset<CharT> const& a, negated_char_parser<ParserT> const& b) +{ + return a - chset<CharT>(b); +} + +////////////////////////////////// +template <typename CharT, typename ParserT> +inline chset<CharT> +operator^(chset<CharT> const& a, negated_char_parser<ParserT> const& b) +{ + return a ^ chset<CharT>(b); +} + +////////////////////////////////// +template <typename CharT, typename ParserT> +inline chset<CharT> +operator|(negated_char_parser<ParserT> const& a, chset<CharT> const& b) +{ + return chset<CharT>(a) | b; +} + +////////////////////////////////// +template <typename CharT, typename ParserT> +inline chset<CharT> +operator&(negated_char_parser<ParserT> const& a, chset<CharT> const& b) +{ + return chset<CharT>(a) & b; +} + +////////////////////////////////// +template <typename CharT, typename ParserT> +inline chset<CharT> +operator-(negated_char_parser<ParserT> const& a, chset<CharT> const& b) +{ + return chset<CharT>(a) - b; +} + +////////////////////////////////// +template <typename CharT, typename ParserT> +inline chset<CharT> +operator^(negated_char_parser<ParserT> const& a, chset<CharT> const& b) +{ + return chset<CharT>(a) ^ b; +} + +#else // BOOST_WORKAROUND(BOOST_MSVC, < 1300) + +/////////////////////////////////////////////////////////////////////////////// +// +// negated_char_parser<range> <--> chset free operators implementation +// +/////////////////////////////////////////////////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator|(chset<CharT> const& a, negated_char_parser<range<CharT> > const& b) +{ + return a | chset<CharT>(b); +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator&(chset<CharT> const& a, negated_char_parser<range<CharT> > const& b) +{ + return a & chset<CharT>(b); +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator-(chset<CharT> const& a, negated_char_parser<range<CharT> > const& b) +{ + return a - chset<CharT>(b); +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator^(chset<CharT> const& a, negated_char_parser<range<CharT> > const& b) +{ + return a ^ chset<CharT>(b); +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator|(negated_char_parser<range<CharT> > const& a, chset<CharT> const& b) +{ + return chset<CharT>(a) | b; +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator&(negated_char_parser<range<CharT> > const& a, chset<CharT> const& b) +{ + return chset<CharT>(a) & b; +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator-(negated_char_parser<range<CharT> > const& a, chset<CharT> const& b) +{ + return chset<CharT>(a) - b; +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator^(negated_char_parser<range<CharT> > const& a, chset<CharT> const& b) +{ + return chset<CharT>(a) ^ b; +} + +/////////////////////////////////////////////////////////////////////////////// +// +// negated_char_parser<chlit> <--> chset free operators implementation +// +/////////////////////////////////////////////////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator|(chset<CharT> const& a, negated_char_parser<chlit<CharT> > const& b) +{ + return a | chset<CharT>(b); +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator&(chset<CharT> const& a, negated_char_parser<chlit<CharT> > const& b) +{ + return a & chset<CharT>(b); +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator-(chset<CharT> const& a, negated_char_parser<chlit<CharT> > const& b) +{ + return a - chset<CharT>(b); +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator^(chset<CharT> const& a, negated_char_parser<chlit<CharT> > const& b) +{ + return a ^ chset<CharT>(b); +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator|(negated_char_parser<chlit<CharT> > const& a, chset<CharT> const& b) +{ + return chset<CharT>(a) | b; +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator&(negated_char_parser<chlit<CharT> > const& a, chset<CharT> const& b) +{ + return chset<CharT>(a) & b; +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator-(negated_char_parser<chlit<CharT> > const& a, chset<CharT> const& b) +{ + return chset<CharT>(a) - b; +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator^(negated_char_parser<chlit<CharT> > const& a, chset<CharT> const& b) +{ + return chset<CharT>(a) ^ b; +} + +#endif // BOOST_WORKAROUND(BOOST_MSVC, < 1300) + +/////////////////////////////////////////////////////////////////////////////// +// +// anychar_parser <--> chset free operators +// +// Where a is chset and b is a anychar_parser, and vice-versa, implements: +// +// a | b, a & b, a - b, a ^ b +// +/////////////////////////////////////////////////////////////////////////////// +namespace impl { + + template <typename CharT> + inline BOOST_SPIRIT_CLASSIC_NS::range<CharT> const& + full() + { + static BOOST_SPIRIT_CLASSIC_NS::range<CharT> full_( + (std::numeric_limits<CharT>::min)(), + (std::numeric_limits<CharT>::max)()); + return full_; + } + + template <typename CharT> + inline BOOST_SPIRIT_CLASSIC_NS::range<CharT> const& + empty() + { + static BOOST_SPIRIT_CLASSIC_NS::range<CharT> empty_; + return empty_; + } +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator|(chset<CharT> const&, anychar_parser) +{ + return chset<CharT>(impl::full<CharT>()); +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator&(chset<CharT> const& a, anychar_parser) +{ + return a; +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator-(chset<CharT> const&, anychar_parser) +{ + return chset<CharT>(); +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator^(chset<CharT> const& a, anychar_parser) +{ + return ~a; +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator|(anychar_parser, chset<CharT> const& /*b*/) +{ + return chset<CharT>(impl::full<CharT>()); +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator&(anychar_parser, chset<CharT> const& b) +{ + return b; +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator-(anychar_parser, chset<CharT> const& b) +{ + return ~b; +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator^(anychar_parser, chset<CharT> const& b) +{ + return ~b; +} + +/////////////////////////////////////////////////////////////////////////////// +// +// nothing_parser <--> chset free operators implementation +// +/////////////////////////////////////////////////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator|(chset<CharT> const& a, nothing_parser) +{ + return a; +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator&(chset<CharT> const& /*a*/, nothing_parser) +{ + return impl::empty<CharT>(); +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator-(chset<CharT> const& a, nothing_parser) +{ + return a; +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator^(chset<CharT> const& a, nothing_parser) +{ + return a; +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator|(nothing_parser, chset<CharT> const& b) +{ + return b; +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator&(nothing_parser, chset<CharT> const& /*b*/) +{ + return impl::empty<CharT>(); +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator-(nothing_parser, chset<CharT> const& /*b*/) +{ + return impl::empty<CharT>(); +} + +////////////////////////////////// +template <typename CharT> +inline chset<CharT> +operator^(nothing_parser, chset<CharT> const& b) +{ + return b; +} + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#endif + diff --git a/boost/spirit/home/classic/utility/impl/confix.ipp b/boost/spirit/home/classic/utility/impl/confix.ipp new file mode 100644 index 0000000000..494c4807cd --- /dev/null +++ b/boost/spirit/home/classic/utility/impl/confix.ipp @@ -0,0 +1,221 @@ +/*============================================================================= + Copyright (c) 2002-2003 Hartmut Kaiser + 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_SPIRIT_CONFIX_IPP +#define BOOST_SPIRIT_CONFIX_IPP + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/spirit/home/classic/meta/refactoring.hpp> +#include <boost/spirit/home/classic/core/composite/impl/directives.ipp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// +// Types to distinguish nested and non-nested confix parsers +// +/////////////////////////////////////////////////////////////////////////////// +struct is_nested {}; +struct non_nested {}; + +/////////////////////////////////////////////////////////////////////////////// +// +// Types to distinguish between confix parsers, which are implicitly lexems +// and without this behaviour +// +/////////////////////////////////////////////////////////////////////////////// +struct is_lexeme {}; +struct non_lexeme {}; + +/////////////////////////////////////////////////////////////////////////////// +// +// confix_parser_type class implementation +// +/////////////////////////////////////////////////////////////////////////////// +namespace impl { + + /////////////////////////////////////////////////////////////////////////// + // implicitly insert a lexeme_d into the parsing process + + template <typename LexemeT> + struct select_confix_parse_lexeme; + + template <> + struct select_confix_parse_lexeme<is_lexeme> { + + template <typename ParserT, typename ScannerT> + static typename parser_result<ParserT, ScannerT>::type + parse(ParserT const& p, ScannerT const& scan) + { + typedef typename parser_result<ParserT, ScannerT>::type result_t; + return contiguous_parser_parse<result_t>(p, scan, scan); + } + }; + + template <> + struct select_confix_parse_lexeme<non_lexeme> { + + template <typename ParserT, typename ScannerT> + static typename parser_result<ParserT, ScannerT>::type + parse(ParserT const& p, ScannerT const& scan) + { + return p.parse(scan); + } + }; + + /////////////////////////////////////////////////////////////////////////// + // parse confix sequences with refactoring + + template <typename NestedT> + struct select_confix_parse_refactor; + + template <> + struct select_confix_parse_refactor<is_nested> { + + template < + typename LexemeT, typename ParserT, typename ScannerT, + typename OpenT, typename ExprT, typename CloseT + > + static typename parser_result<ParserT, ScannerT>::type + parse( + LexemeT const &, ParserT const& this_, ScannerT const& scan, + OpenT const& open, ExprT const& expr, CloseT const& close) + { + typedef refactor_action_gen<refactor_unary_gen<> > refactor_t; + const refactor_t refactor_body_d = refactor_t(refactor_unary_d); + + return select_confix_parse_lexeme<LexemeT>::parse(( + open + >> (this_ | refactor_body_d[expr - close]) + >> close + ), scan); + } + }; + + template <> + struct select_confix_parse_refactor<non_nested> { + + template < + typename LexemeT, typename ParserT, typename ScannerT, + typename OpenT, typename ExprT, typename CloseT + > + static typename parser_result<ParserT, ScannerT>::type + parse( + LexemeT const &, ParserT const& /*this_*/, ScannerT const& scan, + OpenT const& open, ExprT const& expr, CloseT const& close) + { + typedef refactor_action_gen<refactor_unary_gen<> > refactor_t; + const refactor_t refactor_body_d = refactor_t(refactor_unary_d); + + return select_confix_parse_lexeme<LexemeT>::parse(( + open + >> refactor_body_d[expr - close] + >> close + ), scan); + } + }; + + /////////////////////////////////////////////////////////////////////////// + // parse confix sequences without refactoring + + template <typename NestedT> + struct select_confix_parse_no_refactor; + + template <> + struct select_confix_parse_no_refactor<is_nested> { + + template < + typename LexemeT, typename ParserT, typename ScannerT, + typename OpenT, typename ExprT, typename CloseT + > + static typename parser_result<ParserT, ScannerT>::type + parse( + LexemeT const &, ParserT const& this_, ScannerT const& scan, + OpenT const& open, ExprT const& expr, CloseT const& close) + { + return select_confix_parse_lexeme<LexemeT>::parse(( + open + >> (this_ | (expr - close)) + >> close + ), scan); + } + }; + + template <> + struct select_confix_parse_no_refactor<non_nested> { + + template < + typename LexemeT, typename ParserT, typename ScannerT, + typename OpenT, typename ExprT, typename CloseT + > + static typename parser_result<ParserT, ScannerT>::type + parse( + LexemeT const &, ParserT const & /*this_*/, ScannerT const& scan, + OpenT const& open, ExprT const& expr, CloseT const& close) + { + return select_confix_parse_lexeme<LexemeT>::parse(( + open + >> (expr - close) + >> close + ), scan); + } + }; + + // the refactoring is handled by the refactoring parsers, so here there + // is no need to pay attention to these issues. + + template <typename CategoryT> + struct confix_parser_type { + + template < + typename NestedT, typename LexemeT, + typename ParserT, typename ScannerT, + typename OpenT, typename ExprT, typename CloseT + > + static typename parser_result<ParserT, ScannerT>::type + parse( + NestedT const &, LexemeT const &lexeme, + ParserT const& this_, ScannerT const& scan, + OpenT const& open, ExprT const& expr, CloseT const& close) + { + return select_confix_parse_refactor<NestedT>:: + parse(lexeme, this_, scan, open, expr, close); + } + }; + + template <> + struct confix_parser_type<plain_parser_category> { + + template < + typename NestedT, typename LexemeT, + typename ParserT, typename ScannerT, + typename OpenT, typename ExprT, typename CloseT + > + static typename parser_result<ParserT, ScannerT>::type + parse( + NestedT const &, LexemeT const &lexeme, + ParserT const& this_, ScannerT const& scan, + OpenT const& open, ExprT const& expr, CloseT const& close) + { + return select_confix_parse_no_refactor<NestedT>:: + parse(lexeme, this_, scan, open, expr, close); + } + }; + +} // namespace impl + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#endif + diff --git a/boost/spirit/home/classic/utility/impl/escape_char.ipp b/boost/spirit/home/classic/utility/impl/escape_char.ipp new file mode 100644 index 0000000000..55ab158472 --- /dev/null +++ b/boost/spirit/home/classic/utility/impl/escape_char.ipp @@ -0,0 +1,224 @@ +/*============================================================================= + Copyright (c) 2001-2003 Daniel Nuffer + Copyright (c) 2002-2003 Hartmut Kaiser + 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_SPIRIT_ESCAPE_CHAR_IPP +#define BOOST_SPIRIT_ESCAPE_CHAR_IPP + +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/core/primitives/numerics.hpp> +#include <boost/spirit/home/classic/core/composite/difference.hpp> +#include <boost/spirit/home/classic/core/composite/sequence.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// +// escape_char_parser class +// +/////////////////////////////////////////////////////////////////////////////// + +const unsigned long c_escapes = 1; +const unsigned long lex_escapes = c_escapes << 1; + +////////////////////////////////// +namespace impl { + + ////////////////////////////////// +#if (defined(BOOST_MSVC) && (BOOST_MSVC <= 1310)) +#pragma warning(push) +#pragma warning(disable:4127) +#endif + template <unsigned long Flags, typename CharT> + struct escape_char_action_parse { + + template <typename ParserT, typename ScannerT> + static typename parser_result<ParserT, ScannerT>::type + parse(ScannerT const& scan, ParserT const &p) + { + // Actually decode the escape char. + typedef CharT char_t; + typedef typename ScannerT::iterator_t iterator_t; + typedef typename parser_result<ParserT, ScannerT>::type result_t; + + if (scan.first != scan.last) { + + iterator_t save = scan.first; + if (result_t hit = p.subject().parse(scan)) { + + char_t unescaped; + + scan.first = save; + if (*scan.first == '\\') { + + ++scan.first; + switch (*scan.first) { + case 'b': unescaped = '\b'; ++scan.first; break; + case 't': unescaped = '\t'; ++scan.first; break; + case 'n': unescaped = '\n'; ++scan.first; break; + case 'f': unescaped = '\f'; ++scan.first; break; + case 'r': unescaped = '\r'; ++scan.first; break; + case '"': unescaped = '"'; ++scan.first; break; + case '\'': unescaped = '\''; ++scan.first; break; + case '\\': unescaped = '\\'; ++scan.first; break; + + case 'x': case 'X': + { + char_t hex = 0; + char_t const lim = + (std::numeric_limits<char_t>::max)() >> 4; + + ++scan.first; + while (scan.first != scan.last) + { + char_t c = *scan.first; + if (hex > lim && impl::isxdigit_(c)) + { + // overflow detected + scan.first = save; + return scan.no_match(); + } + if (impl::isdigit_(c)) + { + hex <<= 4; + hex |= c - '0'; + ++scan.first; + } + else if (impl::isxdigit_(c)) + { + hex <<= 4; + c = impl::toupper_(c); + hex |= c - 'A' + 0xA; + ++scan.first; + } + else + { + break; // reached the end of the number + } + } + unescaped = hex; + } + break; + + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + { + char_t oct = 0; + char_t const lim = + (std::numeric_limits<char_t>::max)() >> 3; + while (scan.first != scan.last) + { + char_t c = *scan.first; + if (oct > lim && (c >= '0' && c <= '7')) + { + // overflow detected + scan.first = save; + return scan.no_match(); + } + + if (c >= '0' && c <= '7') + { + oct <<= 3; + oct |= c - '0'; + ++scan.first; + } + else + { + break; // reached end of digits + } + } + unescaped = oct; + } + break; + + default: + if (Flags & c_escapes) + { + // illegal C escape sequence + scan.first = save; + return scan.no_match(); + } + else + { + unescaped = *scan.first; + ++scan.first; + } + break; + } + } + else { + unescaped = *scan.first; + ++scan.first; + } + + scan.do_action(p.predicate(), unescaped, save, scan.first); + return hit; + } + } + return scan.no_match(); // overflow detected + } + }; +#if (defined(BOOST_MSVC) && (BOOST_MSVC <= 1310)) +#pragma warning(pop) +#endif + + ////////////////////////////////// + template <typename CharT> + struct escape_char_parse { + + template <typename ScannerT, typename ParserT> + static typename parser_result<ParserT, ScannerT>::type + parse(ScannerT const &scan, ParserT const &/*p*/) + { + typedef + uint_parser<CharT, 8, 1, + std::numeric_limits<CharT>::digits / 3 + 1 + > + oct_parser_t; + typedef + uint_parser<CharT, 16, 1, + std::numeric_limits<CharT>::digits / 4 + 1 + > + hex_parser_t; + + typedef alternative<difference<anychar_parser, chlit<CharT> >, + sequence<chlit<CharT>, alternative<alternative<oct_parser_t, + sequence<inhibit_case<chlit<CharT> >, hex_parser_t > >, + difference<difference<anychar_parser, + inhibit_case<chlit<CharT> > >, oct_parser_t > > > > + parser_t; + + static parser_t p = + ( (anychar_p - chlit<CharT>(CharT('\\'))) + | (chlit<CharT>(CharT('\\')) >> + ( oct_parser_t() + | as_lower_d[chlit<CharT>(CharT('x'))] >> hex_parser_t() + | (anychar_p - as_lower_d[chlit<CharT>(CharT('x'))] - oct_parser_t()) + ) + )); + + BOOST_SPIRIT_DEBUG_TRACE_NODE(p, + (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_ESCAPE_CHAR) != 0); + + return p.parse(scan); + } + }; + +/////////////////////////////////////////////////////////////////////////////// +} // namespace impl + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#endif + diff --git a/boost/spirit/home/classic/utility/impl/lists.ipp b/boost/spirit/home/classic/utility/impl/lists.ipp new file mode 100644 index 0000000000..a3dd462fcd --- /dev/null +++ b/boost/spirit/home/classic/utility/impl/lists.ipp @@ -0,0 +1,168 @@ +/*============================================================================= + Copyright (c) 2002-2003 Hartmut Kaiser + 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_SPIRIT_LISTS_IPP +#define BOOST_SPIRIT_LISTS_IPP + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/spirit/home/classic/meta/refactoring.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// +// list_parser_type class implementation +// +/////////////////////////////////////////////////////////////////////////////// +struct no_list_endtoken { typedef no_list_endtoken embed_t; }; + +namespace impl { + +/////////////////////////////////////////////////////////////////////////////// +// +// Refactor the original list item parser +// +/////////////////////////////////////////////////////////////////////////////// + + // match list with 'extended' syntax + template <typename EndT> + struct select_list_parse_refactor { + + template < + typename ParserT, typename ScannerT, + typename ItemT, typename DelimT + > + static typename parser_result<ParserT, ScannerT>::type + parse(ScannerT const& scan, ParserT const& /*p*/, + ItemT const &item, DelimT const &delim, EndT const &end) + { + typedef refactor_action_gen<refactor_unary_gen<> > refactor_t; + const refactor_t refactor_item_d = refactor_t(refactor_unary_d); + + return ( + refactor_item_d[item - (end | delim)] + >> *(delim >> refactor_item_d[item - (end | delim)]) + >> !(delim >> end) + ).parse(scan); + } + }; + + // match list with 'normal' syntax (without an 'end' parser) + template <> + struct select_list_parse_refactor<no_list_endtoken> { + + template < + typename ParserT, typename ScannerT, + typename ItemT, typename DelimT + > + static typename parser_result<ParserT, ScannerT>::type + parse(ScannerT const& scan, ParserT const& /*p*/, + ItemT const &item, DelimT const &delim, no_list_endtoken const&) + { + typedef refactor_action_gen<refactor_unary_gen<> > refactor_t; + const refactor_t refactor_item_d = refactor_t(refactor_unary_d); + + return ( + refactor_item_d[item - delim] + >> *(delim >> refactor_item_d[item - delim]) + ).parse(scan); + } + }; + +/////////////////////////////////////////////////////////////////////////////// +// +// Do not refactor the original list item parser. +// +/////////////////////////////////////////////////////////////////////////////// + + // match list with 'extended' syntax + template <typename EndT> + struct select_list_parse_no_refactor { + + template < + typename ParserT, typename ScannerT, + typename ItemT, typename DelimT + > + static typename parser_result<ParserT, ScannerT>::type + parse(ScannerT const& scan, ParserT const& /*p*/, + ItemT const &item, DelimT const &delim, EndT const &end) + { + return ( + (item - (end | delim)) + >> *(delim >> (item - (end | delim))) + >> !(delim >> end) + ).parse(scan); + } + }; + + // match list with 'normal' syntax (without an 'end' parser) + template <> + struct select_list_parse_no_refactor<no_list_endtoken> { + + template < + typename ParserT, typename ScannerT, + typename ItemT, typename DelimT + > + static typename parser_result<ParserT, ScannerT>::type + parse(ScannerT const& scan, ParserT const& /*p*/, + ItemT const &item, DelimT const &delim, no_list_endtoken const&) + { + return ( + (item - delim) + >> *(delim >> (item - delim)) + ).parse(scan); + } + }; + + // the refactoring is handled by the refactoring parsers, so here there + // is no need to pay attention to these issues. + + template <typename CategoryT> + struct list_parser_type { + + template < + typename ParserT, typename ScannerT, + typename ItemT, typename DelimT, typename EndT + > + static typename parser_result<ParserT, ScannerT>::type + parse(ScannerT const& scan, ParserT const& p, + ItemT const &item, DelimT const &delim, EndT const &end) + { + return select_list_parse_refactor<EndT>:: + parse(scan, p, item, delim, end); + } + }; + + template <> + struct list_parser_type<plain_parser_category> { + + template < + typename ParserT, typename ScannerT, + typename ItemT, typename DelimT, typename EndT + > + static typename parser_result<ParserT, ScannerT>::type + parse(ScannerT const& scan, ParserT const& p, + ItemT const &item, DelimT const &delim, EndT const &end) + { + return select_list_parse_no_refactor<EndT>:: + parse(scan, p, item, delim, end); + } + }; + +} // namespace impl + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#endif + diff --git a/boost/spirit/home/classic/utility/impl/regex.ipp b/boost/spirit/home/classic/utility/impl/regex.ipp new file mode 100644 index 0000000000..655c1e5c8d --- /dev/null +++ b/boost/spirit/home/classic/utility/impl/regex.ipp @@ -0,0 +1,81 @@ +/*============================================================================= + Copyright (c) 2002-2003 Hartmut Kaiser + 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_SPIRIT_REGEX_IPP +#define BOOST_SPIRIT_REGEX_IPP + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/spirit/home/classic/core/primitives/impl/primitives.ipp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +namespace impl { + +/////////////////////////////////////////////////////////////////////////////// +// +inline const char* rx_prefix(char) { return "\\A"; } +inline const wchar_t* rx_prefix(wchar_t) { return L"\\A"; } + +/////////////////////////////////////////////////////////////////////////////// +// +// rx_parser class +// +/////////////////////////////////////////////////////////////////////////////// +template <typename CharT = char> +class rx_parser : public parser<rx_parser<CharT> > { + +public: + typedef std::basic_string<CharT> string_t; + typedef rx_parser<CharT> self_t; + + rx_parser(CharT const *first, CharT const *last) + { + rxstr = string_t(rx_prefix(CharT())) + string_t(first, last); + } + + rx_parser(CharT const *first) + { + rxstr = string_t(rx_prefix(CharT())) + + string_t(first, impl::get_last(first)); + } + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + boost::match_results<typename ScannerT::iterator_t> what; + boost::regex_search(scan.first, scan.last, what, rxstr, + boost::match_default); + + if (!what[0].matched) + return scan.no_match(); + + scan.first = what[0].second; + return scan.create_match(what[0].length(), nil_t(), + what[0].first, scan.first); + } + +private: +#if BOOST_VERSION >= 013300 + boost::basic_regex<CharT> rxstr; // regular expression to match +#else + boost::reg_expression<CharT> rxstr; // regular expression to match +#endif +}; + +} // namespace impl + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#endif // BOOST_SPIRIT_REGEX_IPP diff --git a/boost/spirit/home/classic/utility/lists.hpp b/boost/spirit/home/classic/utility/lists.hpp new file mode 100644 index 0000000000..48e9de01da --- /dev/null +++ b/boost/spirit/home/classic/utility/lists.hpp @@ -0,0 +1,340 @@ +/*============================================================================= + Copyright (c) 2002-2003 Hartmut Kaiser + 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_LISTS_HPP +#define BOOST_SPIRIT_LISTS_HPP + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/config.hpp> +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/meta/as_parser.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/core/composite/composite.hpp> + +#include <boost/spirit/home/classic/utility/lists_fwd.hpp> +#include <boost/spirit/home/classic/utility/impl/lists.ipp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// +// list_parser class +// +// List parsers allow to parse constructs like +// +// item >> *(delim >> item) +// +// where 'item' is an auxiliary expression to parse and 'delim' is an +// auxiliary delimiter to parse. +// +// The list_parser class also can match an optional closing delimiter +// represented by the 'end' parser at the end of the list: +// +// item >> *(delim >> item) >> !end. +// +// If ItemT is an action_parser_category type (parser with an attached +// semantic action) we have to do something special. This happens, if the +// user wrote something like: +// +// list_p(item[f], delim) +// +// where 'item' is the parser matching one item of the list sequence and +// 'f' is a functor to be called after matching one item. If we would do +// nothing, the resulting code would parse the sequence as follows: +// +// (item[f] - delim) >> *(delim >> (item[f] - delim)) +// +// what in most cases is not what the user expects. +// (If this _is_ what you've expected, then please use one of the list_p +// generator functions 'direct()', which will inhibit re-attaching +// the actor to the item parser). +// +// To make the list parser behave as expected: +// +// (item - delim)[f] >> *(delim >> (item - delim)[f]) +// +// the actor attached to the 'item' parser has to be re-attached to the +// *(item - delim) parser construct, which will make the resulting list +// parser 'do the right thing'. +// +// Additionally special care must be taken, if the item parser is a +// unary_parser_category type parser as +// +// list_p(*anychar_p, ',') +// +// which without any refactoring would result in +// +// (*anychar_p - ch_p(',')) +// >> *( ch_p(',') >> (*anychar_p - ch_p(',')) ) +// +// and will not give the expected result (the first *anychar_p will eat up +// all the input up to the end of the input stream). So we have to +// refactor this into: +// +// *(anychar_p - ch_p(',')) +// >> *( ch_p(',') >> *(anychar_p - ch_p(',')) ) +// +// what will give the correct result. +// +// The case, where the item parser is a combination of the two mentioned +// problems (i.e. the item parser is a unary parser with an attached +// action), is handled accordingly too: +// +// list_p((*anychar_p)[f], ',') +// +// will be parsed as expected: +// +// (*(anychar_p - ch_p(',')))[f] +// >> *( ch_p(',') >> (*(anychar_p - ch_p(',')))[f] ). +// +/////////////////////////////////////////////////////////////////////////////// +template < + typename ItemT, typename DelimT, typename EndT, typename CategoryT +> +struct list_parser : + public parser<list_parser<ItemT, DelimT, EndT, CategoryT> > { + + typedef list_parser<ItemT, DelimT, EndT, CategoryT> self_t; + typedef CategoryT parser_category_t; + + list_parser(ItemT const &item_, DelimT const &delim_, + EndT const& end_ = no_list_endtoken()) + : item(item_), delim(delim_), end(end_) + {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + return impl::list_parser_type<CategoryT> + ::parse(scan, *this, item, delim, end); + } + +private: + typename as_parser<ItemT>::type::embed_t item; + typename as_parser<DelimT>::type::embed_t delim; + typename as_parser<EndT>::type::embed_t end; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// List parser generator template +// +// This is a helper for generating a correct list_parser<> from +// auxiliary parameters. There are the following types supported as +// parameters yet: parsers, single characters and strings (see +// as_parser<> in meta/as_parser.hpp). +// +// The list_parser_gen by itself can be used for parsing comma separated +// lists without item formatting: +// +// list_p.parse(...) +// matches any comma separated list. +// +// If list_p is used with one parameter, this parameter is used to match +// the delimiter: +// +// list_p(';').parse(...) +// matches any semicolon separated list. +// +// If list_p is used with two parameters, the first parameter is used to +// match the items and the second parameter matches the delimiters: +// +// list_p(uint_p, ',').parse(...) +// matches comma separated unsigned integers. +// +// If list_p is used with three parameters, the first parameter is used +// to match the items, the second one is used to match the delimiters and +// the third one is used to match an optional ending token sequence: +// +// list_p(real_p, ';', eol_p).parse(...) +// matches a semicolon separated list of real numbers optionally +// followed by an end of line. +// +// The list_p in the previous examples denotes the predefined parser +// generator, which should be used to define list parsers (see below). +// +/////////////////////////////////////////////////////////////////////////////// + +template <typename CharT = char> +struct list_parser_gen : + public list_parser<kleene_star<anychar_parser>, chlit<CharT> > +{ + typedef list_parser_gen<CharT> self_t; + +// construct the list_parser_gen object as an list parser for comma separated +// lists without item formatting. + list_parser_gen() + : list_parser<kleene_star<anychar_parser>, chlit<CharT> > + (*anychar_p, chlit<CharT>(',')) + {} + +// The following generator functions should be used under normal circumstances. +// (the operator()(...) functions) + + // Generic generator functions for creation of concrete list parsers, which + // support 'normal' syntax: + // + // item >> *(delim >> item) + // + // If item isn't given, everything between two delimiters is matched. + + template<typename DelimT> + list_parser< + kleene_star<anychar_parser>, + typename as_parser<DelimT>::type, + no_list_endtoken, + unary_parser_category // there is no action to re-attach + > + operator()(DelimT const &delim_) const + { + typedef kleene_star<anychar_parser> item_t; + typedef typename as_parser<DelimT>::type delim_t; + + typedef + list_parser<item_t, delim_t, no_list_endtoken, unary_parser_category> + return_t; + + return return_t(*anychar_p, as_parser<DelimT>::convert(delim_)); + } + + template<typename ItemT, typename DelimT> + list_parser< + typename as_parser<ItemT>::type, + typename as_parser<DelimT>::type, + no_list_endtoken, + typename as_parser<ItemT>::type::parser_category_t + > + operator()(ItemT const &item_, DelimT const &delim_) const + { + typedef typename as_parser<ItemT>::type item_t; + typedef typename as_parser<DelimT>::type delim_t; + typedef list_parser<item_t, delim_t, no_list_endtoken, + BOOST_DEDUCED_TYPENAME item_t::parser_category_t> + return_t; + + return return_t( + as_parser<ItemT>::convert(item_), + as_parser<DelimT>::convert(delim_) + ); + } + + // Generic generator function for creation of concrete list parsers, which + // support 'extended' syntax: + // + // item >> *(delim >> item) >> !end + + template<typename ItemT, typename DelimT, typename EndT> + list_parser< + typename as_parser<ItemT>::type, + typename as_parser<DelimT>::type, + typename as_parser<EndT>::type, + typename as_parser<ItemT>::type::parser_category_t + > + operator()( + ItemT const &item_, DelimT const &delim_, EndT const &end_) const + { + typedef typename as_parser<ItemT>::type item_t; + typedef typename as_parser<DelimT>::type delim_t; + typedef typename as_parser<EndT>::type end_t; + + typedef list_parser<item_t, delim_t, end_t, + BOOST_DEDUCED_TYPENAME item_t::parser_category_t> + return_t; + + return return_t( + as_parser<ItemT>::convert(item_), + as_parser<DelimT>::convert(delim_), + as_parser<EndT>::convert(end_) + ); + } + +// The following functions should be used, if the 'item' parser has an attached +// semantic action or is a unary_parser_category type parser and the structure +// of the resulting list parser should _not_ be refactored during parser +// construction (see comment above). + + // Generic generator function for creation of concrete list parsers, which + // support 'normal' syntax: + // + // item >> *(delim >> item) + + template<typename ItemT, typename DelimT> + list_parser< + typename as_parser<ItemT>::type, + typename as_parser<DelimT>::type, + no_list_endtoken, + plain_parser_category // inhibit action re-attachment + > + direct(ItemT const &item_, DelimT const &delim_) const + { + typedef typename as_parser<ItemT>::type item_t; + typedef typename as_parser<DelimT>::type delim_t; + typedef list_parser<item_t, delim_t, no_list_endtoken, + plain_parser_category> + return_t; + + return return_t( + as_parser<ItemT>::convert(item_), + as_parser<DelimT>::convert(delim_) + ); + } + + // Generic generator function for creation of concrete list parsers, which + // support 'extended' syntax: + // + // item >> *(delim >> item) >> !end + + template<typename ItemT, typename DelimT, typename EndT> + list_parser< + typename as_parser<ItemT>::type, + typename as_parser<DelimT>::type, + typename as_parser<EndT>::type, + plain_parser_category // inhibit action re-attachment + > + direct( + ItemT const &item_, DelimT const &delim_, EndT const &end_) const + { + typedef typename as_parser<ItemT>::type item_t; + typedef typename as_parser<DelimT>::type delim_t; + typedef typename as_parser<EndT>::type end_t; + + typedef + list_parser<item_t, delim_t, end_t, plain_parser_category> + return_t; + + return return_t( + as_parser<ItemT>::convert(item_), + as_parser<DelimT>::convert(delim_), + as_parser<EndT>::convert(end_) + ); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// Predefined list parser generator +// +// The list_p parser generator can be used +// - by itself for parsing comma separated lists without item formatting +// or +// - for generating list parsers with auxiliary parser parameters +// for the 'item', 'delim' and 'end' subsequences. +// (see comment above) +// +/////////////////////////////////////////////////////////////////////////////// +const list_parser_gen<> list_p = list_parser_gen<>(); + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif diff --git a/boost/spirit/home/classic/utility/lists_fwd.hpp b/boost/spirit/home/classic/utility/lists_fwd.hpp new file mode 100644 index 0000000000..1defcb6d66 --- /dev/null +++ b/boost/spirit/home/classic/utility/lists_fwd.hpp @@ -0,0 +1,31 @@ +/*============================================================================= + Copyright (c) 2006 Tobias Schwinger + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_LISTS_FWD_HPP) +#define BOOST_SPIRIT_LISTS_FWD_HPP + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + struct no_list_endtoken; + + template < + typename ItemT, typename DelimT, typename EndT = no_list_endtoken, + typename CategoryT = plain_parser_category + > + struct list_parser; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + diff --git a/boost/spirit/home/classic/utility/loops.hpp b/boost/spirit/home/classic/utility/loops.hpp new file mode 100644 index 0000000000..97fc1d3c78 --- /dev/null +++ b/boost/spirit/home/classic/utility/loops.hpp @@ -0,0 +1,317 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2002 Raghavendra Satish + Copyright (c) 2002 Jeff Westfahl + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_LOOPS_HPP) +#define BOOST_SPIRIT_LOOPS_HPP + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/core/composite/composite.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // fixed_loop class + // + // This class takes care of the construct: + // + // repeat_p (exact) [p] + // + // where 'p' is a parser and 'exact' is the number of times to + // repeat. The parser iterates over the input exactly 'exact' times. + // The parse function fails if the parser does not match the input + // exactly 'exact' times. + // + // This class is parametizable and can accept constant arguments + // (e.g. repeat_p (5) [p]) as well as references to variables (e.g. + // repeat_p (ref (n)) [p]). + // + /////////////////////////////////////////////////////////////////////////// + template <typename ParserT, typename ExactT> + class fixed_loop + : public unary<ParserT, parser <fixed_loop <ParserT, ExactT> > > + { + public: + + typedef fixed_loop<ParserT, ExactT> self_t; + typedef unary<ParserT, parser<self_t> > base_t; + + fixed_loop (ParserT const & subject_, ExactT const & exact) + : base_t(subject_), m_exact(exact) {} + + template <typename ScannerT> + typename parser_result <self_t, ScannerT>::type + parse (ScannerT const & scan) const + { + typedef typename parser_result<self_t, ScannerT>::type result_t; + result_t hit = scan.empty_match(); + std::size_t n = m_exact; + + for (std::size_t i = 0; i < n; ++i) + { + if (result_t next = this->subject().parse(scan)) + { + scan.concat_match(hit, next); + } + else + { + return scan.no_match(); + } + } + + return hit; + } + + template <typename ScannerT> + struct result + { + typedef typename match_result<ScannerT, nil_t>::type type; + }; + + private: + + ExactT m_exact; + }; + + /////////////////////////////////////////////////////////////////////////////// + // + // finite_loop class + // + // This class takes care of the construct: + // + // repeat_p (min, max) [p] + // + // where 'p' is a parser, 'min' and 'max' specifies the minimum and + // maximum iterations over 'p'. The parser iterates over the input + // at least 'min' times and at most 'max' times. The parse function + // fails if the parser does not match the input at least 'min' times + // and at most 'max' times. + // + // This class is parametizable and can accept constant arguments + // (e.g. repeat_p (5, 10) [p]) as well as references to variables + // (e.g. repeat_p (ref (n1), ref (n2)) [p]). + // + /////////////////////////////////////////////////////////////////////////////// + template <typename ParserT, typename MinT, typename MaxT> + class finite_loop + : public unary<ParserT, parser<finite_loop<ParserT, MinT, MaxT> > > + { + public: + + typedef finite_loop <ParserT, MinT, MaxT> self_t; + typedef unary<ParserT, parser<self_t> > base_t; + + finite_loop (ParserT const & subject_, MinT const & min, MaxT const & max) + : base_t(subject_), m_min(min), m_max(max) {} + + template <typename ScannerT> + typename parser_result <self_t, ScannerT>::type + parse(ScannerT const & scan) const + { + BOOST_SPIRIT_ASSERT(m_min <= m_max); + typedef typename parser_result<self_t, ScannerT>::type result_t; + result_t hit = scan.empty_match(); + + std::size_t n1 = m_min; + std::size_t n2 = m_max; + + for (std::size_t i = 0; i < n2; ++i) + { + typename ScannerT::iterator_t save = scan.first; + result_t next = this->subject().parse(scan); + + if (!next) + { + if (i >= n1) + { + scan.first = save; + break; + } + else + { + return scan.no_match(); + } + } + + scan.concat_match(hit, next); + } + + return hit; + } + + template <typename ScannerT> + struct result + { + typedef typename match_result<ScannerT, nil_t>::type type; + }; + + private: + + MinT m_min; + MaxT m_max; + }; + + /////////////////////////////////////////////////////////////////////////////// + // + // infinite_loop class + // + // This class takes care of the construct: + // + // repeat_p (min, more) [p] + // + // where 'p' is a parser, 'min' is the minimum iteration over 'p' + // and more specifies that the iteration should proceed + // indefinitely. The parser iterates over the input at least 'min' + // times and continues indefinitely until 'p' fails or all of the + // input is parsed. The parse function fails if the parser does not + // match the input at least 'min' times. + // + // This class is parametizable and can accept constant arguments + // (e.g. repeat_p (5, more) [p]) as well as references to variables + // (e.g. repeat_p (ref (n), more) [p]). + // + /////////////////////////////////////////////////////////////////////////////// + + struct more_t {}; + more_t const more = more_t (); + + template <typename ParserT, typename MinT> + class infinite_loop + : public unary<ParserT, parser<infinite_loop<ParserT, MinT> > > + { + public: + + typedef infinite_loop <ParserT, MinT> self_t; + typedef unary<ParserT, parser<self_t> > base_t; + + infinite_loop ( + ParserT const& subject_, + MinT const& min, + more_t const& + ) + : base_t(subject_), m_min(min) {} + + template <typename ScannerT> + typename parser_result <self_t, ScannerT>::type + parse(ScannerT const & scan) const + { + typedef typename parser_result<self_t, ScannerT>::type result_t; + result_t hit = scan.empty_match(); + std::size_t n = m_min; + + for (std::size_t i = 0; ; ++i) + { + typename ScannerT::iterator_t save = scan.first; + result_t next = this->subject().parse(scan); + + if (!next) + { + if (i >= n) + { + scan.first = save; + break; + } + else + { + return scan.no_match(); + } + } + + scan.concat_match(hit, next); + } + + return hit; + } + + template <typename ScannerT> + struct result + { + typedef typename match_result<ScannerT, nil_t>::type type; + }; + + private: + + MinT m_min; + }; + + template <typename ExactT> + struct fixed_loop_gen + { + fixed_loop_gen (ExactT const & exact) + : m_exact (exact) {} + + template <typename ParserT> + fixed_loop <ParserT, ExactT> + operator[](parser <ParserT> const & subject_) const + { + return fixed_loop <ParserT, ExactT> (subject_.derived (), m_exact); + } + + ExactT m_exact; + }; + + namespace impl { + + template <typename ParserT, typename MinT, typename MaxT> + struct loop_traits + { + typedef typename mpl::if_< + boost::is_same<MaxT, more_t>, + infinite_loop<ParserT, MinT>, + finite_loop<ParserT, MinT, MaxT> + >::type type; + }; + + } // namespace impl + + template <typename MinT, typename MaxT> + struct nonfixed_loop_gen + { + nonfixed_loop_gen (MinT min, MaxT max) + : m_min (min), m_max (max) {} + + template <typename ParserT> + typename impl::loop_traits<ParserT, MinT, MaxT>::type + operator[](parser <ParserT> const & subject_) const + { + typedef typename impl::loop_traits<ParserT, MinT, MaxT>::type ret_t; + return ret_t( + subject_.derived(), + m_min, + m_max); + } + + MinT m_min; + MaxT m_max; + }; + + template <typename ExactT> + fixed_loop_gen <ExactT> + repeat_p(ExactT const & exact) + { + return fixed_loop_gen <ExactT> (exact); + } + + template <typename MinT, typename MaxT> + nonfixed_loop_gen <MinT, MaxT> + repeat_p(MinT const & min, MaxT const & max) + { + return nonfixed_loop_gen <MinT, MaxT> (min, max); + } + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif // #if !defined(BOOST_SPIRIT_LOOPS_HPP) diff --git a/boost/spirit/home/classic/utility/regex.hpp b/boost/spirit/home/classic/utility/regex.hpp new file mode 100644 index 0000000000..e8286d5812 --- /dev/null +++ b/boost/spirit/home/classic/utility/regex.hpp @@ -0,0 +1,112 @@ +/*============================================================================= + Copyright (c) 2002-2003 Hartmut Kaiser + 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_REGEX_HPP +#define BOOST_SPIRIT_REGEX_HPP + +#include <boost/version.hpp> + +/////////////////////////////////////////////////////////////////////////////// +// +// Include the regular expression library of boost (Boost.Regex) +// +// Note though, that this library is not distributed with Spirit. You have to +// obtain a separate copy from http://www.boost.org. +// +/////////////////////////////////////////////////////////////////////////////// +#if defined(BOOST_SPIRIT_NO_REGEX_LIB) && BOOST_VERSION < 103300 +// +// Include all the Boost.regex library. Please note that this will not work, +// if you are using the boost/spirit/regex.hpp header from more than one +// translation units. +// +#define BOOST_REGEX_NO_LIB +#define BOOST_REGEX_STATIC_LINK +#define BOOST_REGEX_NO_EXTERNAL_TEMPLATES +#include <boost/regex.hpp> +#include <boost/regex/src.cpp> + +#else +// +// Include the Boost.Regex headers only. Note, that you will have to link your +// application against the Boost.Regex library as described in the related +// documentation. +// This is the only way for Boost newer than V1.32.0 +// +#include <boost/regex.hpp> +#endif // defined(BOOST_SPIRIT_NO_REGEX_LIB) + +#include <boost/static_assert.hpp> + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/meta/as_parser.hpp> +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/utility/impl/regex.ipp> +#include <boost/detail/iterator.hpp> // for boost::detail::iterator_traits + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// rxstrlit class +template <typename CharT = char> +struct rxstrlit : public parser<rxstrlit<CharT> > { + + typedef rxstrlit self_t; + + rxstrlit(CharT const *first, CharT const *last) + : rx(first, last) {} + rxstrlit(CharT const *first) + : rx(first) {} + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const& scan) const + { + // Due to limitations in the boost::regex library the iterators wrapped in + // the ScannerT object should be at least bidirectional iterators. Plain + // forward iterators do not work here. + typedef typename ScannerT::iterator_t iterator_t; + typedef + typename boost::detail::iterator_traits<iterator_t>::iterator_category + iterator_category; + + BOOST_STATIC_ASSERT(( + boost::is_convertible<iterator_category, + std::bidirectional_iterator_tag>::value + )); + + typedef typename parser_result<self_t, ScannerT>::type result_t; + return impl::contiguous_parser_parse<result_t>(rx, scan, scan); + } + +private: + impl::rx_parser<CharT> rx; // contains the boost regular expression parser +}; + +/////////////////////////////////////////////////////////////////////////////// +// Generator functions +template <typename CharT> +inline rxstrlit<CharT> +regex_p(CharT const *first) +{ return rxstrlit<CharT>(first); } + +////////////////////////////////// +template <typename CharT> +inline rxstrlit<CharT> +regex_p(CharT const *first, CharT const *last) +{ return rxstrlit<CharT>(first, last); } + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif // BOOST_SPIRIT_REGEX_HPP diff --git a/boost/spirit/home/classic/utility/rule_parser.hpp b/boost/spirit/home/classic/utility/rule_parser.hpp new file mode 100644 index 0000000000..9cacb49940 --- /dev/null +++ b/boost/spirit/home/classic/utility/rule_parser.hpp @@ -0,0 +1,1142 @@ +/*============================================================================== + Copyright (c) 2006 Tobias Schwinger + 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) +==============================================================================*/ +// The comment below contains a unnamed 'namespace {', which is flagged by the +// Boost inspect tool as a violation of common C++ programming rules. Since it's +// in a comment, well, we switch it off :-P +// boostinspect:nounnamed + +// +// About: +// ===== +// +// Using a typeof operator or Boost.Typeof to automatically set the type of +// variables (as done in the Spirit example demonstrating typeof) is by far not +// all we can do to tighten up our grammars as there are some significant +// drawbacks of this approach: +// - the types complexity scales with the complexity of the grammar (sooner or +// later hitting the limits of the compiler), +// - recursive grammars are not possible, and +// - all parser objects are embedded by value. +// +// The Spirit documentation therefore recommends creating custom parser classes +// (derived from the a sub_grammar template): +// +// http://www.boost.org/libs/spirit/doc/techniques.html#no_rules +// http://www.boost.org/libs/spirit/doc/techniques.html#typeof +// +// In practice manually applying this technique leads to rather lengthy code and +// overthis requires the user to have a solid understanding of Spirit details. +// +// Here is a generalized, macro-based approach to easily create typeof-based +// grammars that can be recursive and arbitrarily complex. +// +// +// Quick manual: +// ============ +// +// 1. Setup +// +// Before the rule parser macro (the protagonist of the facility) can be used +// the the user must define the macro BOOST_SPIRIT__NAMESPACE (note the double +// underscore characeter) and setup a registration group for Boost.Typeof. +// +// Examples: +// +// // should come after regular #includeS +// #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() +// +// // [...] +// +// #define BOOST_SPIRIT__NAMESPACE (2,(my_project, my_module)) +// // | | +- outer +- inner +// // ! space ! -+ | namespace namespace +// // | +// // +--- number of nested namespaces +// +// namespace my_project { namespace my_module { +// +// // [...] +// +// --- +// +// // should come after regular #includeS +// #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() +// +// // [...] +// +// #define BOOST_SPIRIT__NAMESPACE (2,(my_project, (anonymous) )) +// +// namespace my_project { namespace { +// +// // [...] +// +// --- +// +// // should come after regular #includeS +// #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() +// +// // [...] +// +// +// #define BOOST_SPIRIT__NAMESPACE - +// // we're working at root namespace +// +// +// Why do I have to do this? +// +// Boost.Typeof needs to assign a unique ID for each registration. This ID is +// created composed of the line number and the registration group. The +// facility performs Typeof registration and thus requires the source file to +// have its own registration group. Further Boost.Typeof requires registration +// to happen at root namespace so we have to close and reopen the namespace +// we're in. +// +// +// 2. The rule parser macro +// +// A simple rule parser definition looks like that: +// +// // we're at namespace scope here +// +// // Skip parser for C/C++ comments and whitespace +// BOOST_SPIRIT_RULE_PARSER(skipper, +// -,-,-, +// +// +( confix_p("//",*anychar_p,eol_p) +// | confix_p("/*",*anychar_p,"*/") +// | space_p +// ) +// ) +// +// Now we can use 'skipper' in other Spirit expressions. +// +// The code above creates a parser (template) class 'skpper_t' and (in this +// case, because there are no parameters) a static const instance 'skipper' of +// that class. The class is automatically registered with Boost.Typeof. The type +// name our parser is skipper_t here. +// +// +// 2.1. Parametrized rule parsers +// +// Rule parser definitions can have parameters. +// +// Parameters are passed to the BOOST_SPIRIT_RULE_PARSER macro as its second +// argument (just pass '-' if there are no parameters) with the following +// format: +// +// (N,( param1,param2, / ... / paramN )) +// +-- number of parameters +// +// Example of a whole rule parser: +// +// BOOST_SPIRIT_RULE_PARSER(new_name, +// (1,( symbol_table )),-,-, +// +// lexeme_d[ (alpha_p >> *alnum_p)[ symbol_table.add ] ] +// ) +// +// The expression 'new_name(my_symbols)' parses a string literal and adds it to +// the symbol table 'my_symbols'. +// +// The rule parser macro creates a function template as called 'new_name' that +// takes one parameter of deduced reference type and returns a specialization of +// 'new_name_t' in this case. +// +// Since parsers that require to be fast and lightweight often also require to +// be reentrant, it's quite common to pass in some semantic controller (the +// symbol table in the example above). +// However, parameters are templated so they can be anything (including parsers +// of course) so refactoring tasks can be abstracted with rule parsers as well. +// +// BOOST_SPIRIT_RULE_PARSER(enumeration_parser, +// (2,( element_parser, delimiter_parser )),-,-, +// +// element_parser >> *(delimiter_parser >> element_parser) +// ) +// +// The expression 'enumeration_parser(int_p[ some_action ], ',')' creates a +// parser for a comma-separated list of integers. +// +// +// 2.2. Rule parsrs and semantic actions +// +// While semantic actions can be globally attached to a rule parser or passed +// to a parametrized rule parser as (part of) an argument, even more control is +// possible by using action placeholders. E.g: +// +// BOOST_SPIRIT_ACTION_PLACEHOLDER(int_action) +// +// BOOST_SPIRIT_RULE_PARSER(int_list, +// -,(1,( int_action )),-, +// +// int_p[ int_action ] >> *(',' >> int_p[ int_action ]) +// ) +// +// The expression 'int_list[ my_action ]' parses a comma separated list of +// integers and calls 'my_action' for every integer parsed therein. +// +// Of course multiple actions can be attached to one placeholder as usual (in +// this case 'int_list[ my_action1 ][ my_action2 ] would call two actions). +// +// Further there can be multiple action placeholders for a single rule parser: +// +// BOOST_SPIRIT_ACTION_PLACEHOLDER(feed_int) +// BOOST_SPIRIT_ACTION_PLACEHOLDER(next_int) +// +// BOOST_SPIRIT_RULE_PARSER(int_list, +// -,(2,( feed_int, next_int )),-, +// +// int_p[ feed_int ] >> *(',' >> int_p[ next_int ][ feed_int ]) +// ) +// +// The expression 'int_list[ (feed_int = my_action1), (next_int = my_action2) ]' +// creates a parser for a comma separated list of integers with the actions +// attached appropriately. +// +// int_list[ feed_int = my_action1,my_action2, next_int = my_action3 ] +// +// works too (in this case the action placeholder 'feed_int' has two actions +// attached to it). +// +// You can both override and append actions associated with an action +// placeholder: +// +// var = int_list[ feed_int = my_action1, next_int = my_action2 ] +// +// // [...] +// +// ... var[ feed_int = another_action ] +// // 'another_action' overrides the actions previously attached to 'feed_int' +// +// ... var[ next_int += another_action ] +// // 'another_action' is appended to the list of actions attached to +// // 'next_int' +// +// Action placeholders are not entirely for free -- they add to the size and the +// initialization time of the rule parser. However, the impact on an already +// initialized rule parser instance should be quite small. +// +// +// 2.3. Member variables +// +// You can add member variables to the rule parser class using the third +// parameter of the rule parser macro: +// +// BOOST_SPIRIT_RULE_PARSER( calc, +// -, +// -, +// (3,( ((subrule<0>),expression,()), +// ((subrule<1>),term,()), +// ((subrule<2>),factor,() )) ), +// +// // [...] +// +// adds three subrules to the rule parser. +// Each parameter must have the following type to allow commas to be handled +// safely from within the preprocessing code: +// +// ((type)),name,(constructor argument(s))) +// +// +// 2.4. The opaque rule parser +// +// Rule parsers usually are templates. Building large grammars pushes the +// compiler really hard (and eventually to its limits) because of the +// metafunction complexity involved. +// If a rule parser without parameters and action placeholders is defined, a +// non-template class is created. Non-templated rule parsers can also be created +// explicitly by using BOOST_SPIRIT_OPAQUE_RULE_PARSER. +// Opaque rule parsers can have parameters and member variables (note: no action +// placeholders are possible). The parameters of an opaque rule parsers are +// strictly typed, e.g: +// +// BOOST_SPIRIT_OPAQUE_RULE_PARSER(new_identifier, +// (1,( ((my_symbol_table_t &),symbol_table) )) +// ,-, +// (alpha_p >> *alnum_p) [ symbol_table.add ] +// ) +// +// Note it's also possible to have opaque rule parsers accept parameters of +// non-const reference types which is not possible with regular rule parsers. +// +// +// 3. Utilities for by-reference embedding +// +// When using parsers mutiple times or recursively it can be helpful to embed +// them by-reference into the final parser expression. +// For this purpose the library provides a wrapper template 'parser_reference'. +// There is also a function template to create a wrapped parser which can deduce +// the parser's type from its argument. +// +// --- --- - - --- - - --- - - - - --- - - - - - - - - - - - - - - - - - - - - - +#if !defined(BOOST_SPIRIT_UTILITY_RULE_PARSER_HPP_INCLUDED) +# define BOOST_SPIRIT_UTILITY_RULE_PARSER_HPP_INCLUDED +//============================================================================== +// Dependencies +//============================================================================== +# include <boost/config.hpp> +# include <boost/detail/workaround.hpp> +# include <boost/call_traits.hpp> +# include <boost/typeof/typeof.hpp> +# include <boost/spirit/home/classic/namespace.hpp> +# include <boost/spirit/home/classic/core/parser.hpp> +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# include <boost/preprocessor/cat.hpp> +# include <boost/preprocessor/seq/seq.hpp> +# include <boost/preprocessor/seq/for_each_i.hpp> +# include <boost/preprocessor/tuple/eat.hpp> +# include <boost/preprocessor/tuple/to_seq.hpp> +# include <boost/preprocessor/array/size.hpp> +# include <boost/preprocessor/control/if.hpp> +# include <boost/preprocessor/control/iif.hpp> +# include <boost/preprocessor/control/expr_iif.hpp> +# include <boost/preprocessor/logical/or.hpp> +# include <boost/preprocessor/logical/nor.hpp> +# include <boost/preprocessor/logical/not.hpp> +# include <boost/preprocessor/logical/compl.hpp> +# include <boost/preprocessor/arithmetic/inc.hpp> +# include <boost/preprocessor/arithmetic/dec.hpp> +# include <boost/preprocessor/arithmetic/add.hpp> +# include <boost/preprocessor/detail/is_unary.hpp> +# include <boost/preprocessor/detail/is_binary.hpp> +# include <boost/preprocessor/repetition/repeat.hpp> +# include <boost/preprocessor/repetition/enum_params.hpp> +# include <boost/preprocessor/repetition/enum_binary_params.hpp> +# include <boost/preprocessor/repetition/enum_shifted_params.hpp> +# include <boost/preprocessor/repetition/enum_trailing_params.hpp> +# include <boost/preprocessor/punctuation/comma.hpp> +# include <boost/preprocessor/punctuation/comma_if.hpp> +# include <boost/preprocessor/facilities/empty.hpp> +# include <boost/preprocessor/facilities/identity.hpp> +# include <boost/preprocessor/facilities/intercept.hpp> +//============================================================================== +// Interface +//============================================================================== +// Creates a rule parser. Use at namespace scope. +# define BOOST_SPIRIT_RULE_PARSER(name,params,actions,members,rule) \ + BOOST_SPIRIT_RP_IMPL_I(name,params,actions,members,rule) +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// Creates a non-templated rule parser. Use at namespace scope. +# define BOOST_SPIRIT_OPAQUE_RULE_PARSER(name,params,members,rule) \ + BOOST_SPIRIT_RP_OPAQUE_IMPL_I(name,params,members,rule) +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// Defines an action placeholder. Use at namespace scope. +# define BOOST_SPIRIT_ACTION_PLACEHOLDER(name) \ + BOOST_SPIRIT_RP_AP_IMPL(name,::BOOST_SPIRIT_CLASSIC_NS::type_of) +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// Utilities to embed parsers by reference. +namespace boost +{ + namespace spirit + { + BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + template<class P> class parser_reference; + template<class P> parser_reference<P> embed_by_reference(parser<P> const &); + + BOOST_SPIRIT_CLASSIC_NAMESPACE_END + } +} +//============================================================================== +// Implementation +//============================================================================== +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// RP_REGISTER_TEMPLATE +// +// Boost.Typeof registration from within BOOST_SPIRIT__NAMESPACE +# define BOOST_SPIRIT_RP_REGISTER_TEMPLATE(name,params) \ + BOOST_SPIRIT_RP_EMIT(NS_CLOSE,BOOST_SPIRIT__NAMESPACE,-) \ + BOOST_TYPEOF_REGISTER_TEMPLATE( \ + BOOST_SPIRIT_RP_EMIT(NS_QUALIFY,BOOST_SPIRIT__NAMESPACE,-) name, \ + params) \ + BOOST_SPIRIT_RP_EMIT(NS_OPEN,BOOST_SPIRIT__NAMESPACE,-) +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// RP_REGISTER_TYPE +// +// Boost.Typeof registration from within BOOST_SPIRIT__NAMESPACE +# define BOOST_SPIRIT_RP_REGISTER_TYPE(name) \ + BOOST_SPIRIT_RP_EMIT(NS_CLOSE,BOOST_SPIRIT__NAMESPACE,-) \ + BOOST_TYPEOF_REGISTER_TYPE( \ + BOOST_SPIRIT_RP_EMIT(NS_QUALIFY,BOOST_SPIRIT__NAMESPACE,-) name ) \ + BOOST_SPIRIT_RP_EMIT(NS_OPEN,BOOST_SPIRIT__NAMESPACE,-) +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// RP_AP_IMPL +// +// The action placeholder definition +# define BOOST_SPIRIT_RP_AP_IMPL(name,ns) \ + namespace __action_placeholder \ + { \ + struct name \ + { \ + template<typename Action> \ + ns :: action_chain< name, ns :: replace, Action> \ + operator=(Action const & __a) const \ + { return ns :: action_chain< name, ns :: replace, Action>(__a); } \ + \ + template<typename Action> \ + ns :: action_chain< name, ns :: append, Action> \ + operator+=(Action const & __a) const \ + { return ns :: action_chain< name, ns :: append, Action> (__a); } \ + }; \ + } \ + __action_placeholder:: name const name = __action_placeholder:: name (); +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// RP_IMPL_I +// +// Does some precalculation so RP_IMPL_II can look cleaner +# define BOOST_SPIRIT_RP_IMPL_I(name,pars,acts,mbrs,expr) \ + BOOST_SPIRIT_RP_IMPL_II(name, name ## _t , \ + pars, BOOST_SPIRIT_RP_ARRAY_SIZE(pars), \ + acts, BOOST_SPIRIT_RP_ARRAY_SIZE(acts), \ + mbrs, BOOST_SPIRIT_RP_ARRAY_SIZE(mbrs), expr) +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// RP_IMPL_II +# define BOOST_SPIRIT_RP_IMPL_II(name,name_t,pars,np,acts,na,mbrs,nm,x) \ + BOOST_PP_IIF(BOOST_PP_OR(np,na),BOOST_SPIRIT_RP_IMPL_III, \ + BOOST_SPIRIT_RP_OPAQUE_IMPL_II) \ + (name,name_t,pars,np,acts,na,mbrs,nm,x) +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// RP_IMPL_III +// +// The rule parser definition +# define BOOST_SPIRIT_RP_IMPL_III(name,name_t,pars,np,acts,na,mbrs,nm,x) \ + \ + template< BOOST_SPIRIT_RP_TPL_PARAMS(pars,acts,typename __,1) > \ + class name_t \ + : public ::BOOST_SPIRIT_CLASSIC_NS::parser< name_t \ + < BOOST_SPIRIT_RP_TPL_PARAMS(pars,acts,__,0) > > \ + { \ + class __rule \ + { \ + BOOST_SPIRIT_RP_EMIT(PM_STATIC,pars,__T) \ + BOOST_SPIRIT_RP_EMIT(AP_STATIC,acts,-) \ + BOOST_SPIRIT_RP_EMIT(MV_STATIC,mbrs,BOOST_PP_IDENTITY(typename)) \ + public: \ + BOOST_TYPEOF_NESTED_TYPEDEF_TPL(__expr, \ + ::BOOST_SPIRIT_CLASSIC_NS::type_of::depend_on_type<__Dummy>(x) ) \ + }; \ + \ + public: \ + \ + typedef name_t self_t; \ + typedef typename __rule::__expr::type::parser_category_t \ + parser_category_t; \ + \ + BOOST_PP_EXPR_IIF(BOOST_PP_NOR(np,na),typedef self_t const & embed_t;) \ + \ + protected: \ + \ + BOOST_SPIRIT_RP_EMIT(MV_NONSTATIC,mbrs,BOOST_PP_IDENTITY(typename)) \ + BOOST_SPIRIT_RP_IF(na,SPIRIT_RP_AP_EXTRA_MBRS,2)(np,na) \ + \ + typename __rule::__expr::type::embed_t __parser; \ + \ + public: \ + \ + explicit name_t ( BOOST_SPIRIT_RP_CTOR(PARAMS,pars,np,acts) ) \ + : BOOST_SPIRIT_RP_EMIT(MV_CTOR_INIT_LIST,mbrs,-) \ + BOOST_PP_COMMA_IF(nm) \ + BOOST_SPIRIT_RP_IF(na,SPIRIT_RP_CTOR_COMMA,4)(INIT_LIST,pars,np,acts)\ + __parser(x) \ + { } \ + \ + name_t( name_t const & that) \ + : BOOST_SPIRIT_RP_EMIT(MV_CTOR_COPY_INIT_LIST,mbrs,that) \ + BOOST_PP_COMMA_IF(nm) \ + BOOST_SPIRIT_RP_IF(na,SPIRIT_RP_CTOR_COMMA,4) \ + (COPY_INIT_LIST,pars,np,acts) \ + __parser(that.__parser) \ + { } \ + \ + template<typename Scanner> struct result \ + { \ + typedef typename ::BOOST_SPIRIT_CLASSIC_NS::parser_result< \ + typename __rule::__expr::type, Scanner>::type type; \ + }; \ + \ + template<typename Scanner> \ + typename ::BOOST_SPIRIT_CLASSIC_NS::parser_result<self_t, Scanner>::type \ + parse(Scanner const & s) const { return __parser.parse(s); } \ + \ + BOOST_SPIRIT_RP_IF(na,SPIRIT_RP_AP_HANDLER,5) \ + (name_t,np,acts,na,::BOOST_SPIRIT_CLASSIC_NS::type_of) \ + }; \ + \ + BOOST_PP_IF(np,BOOST_SPIRIT_RP_GEN_FUNC,BOOST_SPIRIT_RP_GLOB_VAR) \ + (name,name_t,np,na) \ + BOOST_SPIRIT_RP_REGISTER_TEMPLATE \ + (name_t,BOOST_PP_INC(BOOST_PP_ADD(np,na))) +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// RP_OPAQUE_IMPL_I +// +# define BOOST_SPIRIT_RP_OPAQUE_IMPL_I(name,pars,mbrs,expr) \ + BOOST_SPIRIT_RP_OPAQUE_IMPL_II(name, name ## _t, \ + pars,BOOST_SPIRIT_RP_ARRAY_SIZE(pars),-,-,\ + mbrs,BOOST_SPIRIT_RP_ARRAY_SIZE(mbrs),expr) +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// RP_OPAQUE_IMPL_II +// +# define BOOST_SPIRIT_RP_OPAQUE_IMPL_II(name,name_t,pars,np,_1,_2,mbrs,nm,x) \ + class name_t; \ + \ + BOOST_SPIRIT_RP_REGISTER_TYPE(name_t) \ + \ + class name_t \ + : public ::BOOST_SPIRIT_CLASSIC_NS::parser< name_t > \ + { \ + class __rule \ + { \ + BOOST_SPIRIT_RP_EMIT(PM_OPAQUE_STATIC,pars,-) \ + BOOST_SPIRIT_RP_EMIT(MV_STATIC,mbrs,BOOST_PP_EMPTY) \ + public: \ + BOOST_TYPEOF_NESTED_TYPEDEF(__expr,x) \ + }; \ + \ + public: \ + \ + typedef name_t self_t; \ + typedef __rule::__expr::type::parser_category_t parser_category_t; \ + BOOST_PP_EXPR_IIF(BOOST_PP_NOT(np),typedef self_t const & embed_t;) \ + \ + protected: \ + \ + BOOST_SPIRIT_RP_EMIT(MV_NONSTATIC,mbrs,BOOST_PP_EMPTY) \ + \ + __rule::__expr::type::embed_t __parser; \ + \ + public: \ + \ + explicit name_t (BOOST_SPIRIT_RP_EMIT(PM_OPAQUE_CTOR_PARAMS,pars,-)) \ + : BOOST_SPIRIT_RP_EMIT(MV_CTOR_INIT_LIST,mbrs,-) \ + BOOST_PP_COMMA_IF(nm) __parser(x) \ + { } \ + \ + name_t(name_t const & that) \ + : BOOST_SPIRIT_RP_EMIT(MV_CTOR_COPY_INIT_LIST,mbrs,that) \ + BOOST_PP_COMMA_IF(nm) __parser(that.__parser) \ + { } \ + \ + template<typename Scanner> struct result \ + { \ + typedef typename ::BOOST_SPIRIT_CLASSIC_NS::parser_result< \ + __rule::__expr::type, Scanner>::type type; \ + }; \ + \ + template<typename Scanner> \ + typename ::BOOST_SPIRIT_CLASSIC_NS::parser_result<self_t, Scanner>::type \ + parse(Scanner const & s) const { return __parser.parse(s); } \ + }; \ + \ + BOOST_PP_IF(np,BOOST_SPIRIT_RP_GEN_OPAQUE,BOOST_SPIRIT_RP_GLOB_OPAQUE) \ + (name,name_t,np,pars) +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// RP_AP_HANDLER +// +// Part of the rule parser definition for handling action placeholders +# define BOOST_SPIRIT_RP_AP_HANDLER(name_t,np,acts,na,ns) \ + private: \ + template<typename A> struct __rebound_1st \ + { \ + typedef name_t < void BOOST_PP_ENUM_TRAILING_PARAMS(np,__T) , \ + typename ns ::action_concatenator<__A0,A>::type \ + BOOST_PP_COMMA_IF(BOOST_PP_DEC(na)) \ + BOOST_PP_ENUM_SHIFTED_PARAMS(na,__A) \ + > type; \ + }; \ + \ + template<typename X> struct __rebound \ + { \ + typedef name_t < \ + void BOOST_PP_ENUM_TRAILING_PARAMS(np,__T) \ + BOOST_SPIRIT_RP_EMIT(AP_REBOUND_TPL_ARGS,acts,X) \ + > type; \ + }; \ + public: \ + template<typename A> \ + typename __rebound_1st<A>::type const operator[](A const & a) const \ + { \ + return typename __rebound_1st<A>::type ( \ + BOOST_PP_ENUM_PARAMS(np,__p) BOOST_PP_COMMA_IF(np) \ + ns ::concatenate_actions(__a0,a) \ + BOOST_PP_COMMA_IF(BOOST_PP_DEC(na)) \ + BOOST_PP_ENUM_SHIFTED_PARAMS(na,__a) ); \ + } \ + template<class PH, ns ::action_chain_mode M, typename A> \ + typename __rebound< ns ::action_chain<PH,M,A> >::type const \ + operator[]( ns ::action_chain<PH,M,A> const & x) const \ + { \ + return typename __rebound< ns ::action_chain<PH,M,A> >::type ( \ + BOOST_PP_ENUM_PARAMS(np,__p) BOOST_PP_COMMA_IF(np) \ + BOOST_SPIRIT_RP_EMIT(AP_REBOUND_ARGS,acts,x) ); \ + } \ + template<class Head, class Tail> \ + typename __rebound< ns ::action_chains<Head,Tail> >::type const \ + operator[]( ns ::action_chains<Head,Tail> const & x) const \ + { \ + return typename __rebound< ns ::action_chains<Head,Tail> >::type ( \ + BOOST_PP_ENUM_PARAMS(np,__p) BOOST_PP_COMMA_IF(np) \ + BOOST_SPIRIT_RP_EMIT(AP_REBOUND_ARGS,acts,x) ); \ + } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// RP_AP_EXTRA_MBRS +// +// Extra members we need for rebinding if there are action placeholders +# define BOOST_SPIRIT_RP_AP_EXTRA_MBRS(np,na) \ + private: \ + BOOST_PP_REPEAT(np,BOOST_SPIRIT_RP_PM_MBRS,-) \ + BOOST_PP_REPEAT(na,BOOST_SPIRIT_RP_AP_MBRS,-) +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// RP_PM_MBRS +// +// Member variables to remember parameters if there are action placeholder +# define BOOST_SPIRIT_RP_PM_MBRS(z,i,d) __T ## i __p ## i ; +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// RP_AP_MBRS +// +// Member variables to remember action placeholder substitutes +# define BOOST_SPIRIT_RP_AP_MBRS(z,i,d) __A ## i __a ## i ; +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// RP_CTOR +// +// Expands to a fragment of a constructor (parameters or init-list) +# define BOOST_SPIRIT_RP_CTOR(what,pars,np,acts) \ + BOOST_SPIRIT_RP_EMIT(PM_CTOR_ ## what,pars,__T) \ + BOOST_SPIRIT_RP_EMIT(AP_CTOR_ ## what,acts,np) +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// RP_CTOR_COMMA +// +// RP_CTOR with a trailing comma +# define BOOST_SPIRIT_RP_CTOR_COMMA(what,pars,np,acts) \ + BOOST_SPIRIT_RP_CTOR(what,pars,np,acts) , +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// RP_TPL_PARAMS +// +// Expands to the template parameters or arguments of the rule parser template +# define BOOST_SPIRIT_RP_TPL_PARAMS(pars,acts,prefix,defaults) \ + prefix ## Dummy \ + BOOST_SPIRIT_RP_EMIT(PM_TEMPLATE_PARAMS,pars,prefix ## T) \ + BOOST_SPIRIT_RP_EMIT(AP_TEMPLATE_PARAMS,acts,(prefix ## A,defaults)) +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// RP_GEN_FUNC +// +// Generator function +# define BOOST_SPIRIT_RP_GEN_FUNC(name,name_t,np,na) \ + template< BOOST_PP_ENUM_PARAMS(np,typename T) > \ + inline name_t < void BOOST_PP_ENUM_TRAILING_PARAMS(np,T) > \ + name( BOOST_PP_ENUM_BINARY_PARAMS(np,T, const & p) ) \ + { return name_t < void BOOST_PP_ENUM_TRAILING_PARAMS(np,T) > \ + (BOOST_PP_ENUM_PARAMS(np,p) BOOST_PP_ENUM_TRAILING_PARAMS(na, \ + ::BOOST_SPIRIT_CLASSIC_NS::type_of::nop_functor() BOOST_PP_INTERCEPT) ); \ + } +// RP_GEN_OPAQUE +// +// non-templated version for opaque rule parsers. +# define BOOST_SPIRIT_RP_GEN_OPAQUE(name,name_t,np,pars) \ + inline name_t name( BOOST_SPIRIT_RP_EMIT(PM_OPAQUE_GEN_PARAMS,pars,p)) \ + { return name_t (BOOST_PP_ENUM_PARAMS(np,p)); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// RP_GLOB_VAR +// +// Global variable -- used instead of the generator function if there are no +// parameters +# define BOOST_SPIRIT_RP_GLOB_VAR(name,name_t,np,na) \ + static name_t <void> const name = name_t <void>(BOOST_PP_ENUM_PARAMS(na, \ + ::BOOST_SPIRIT_CLASSIC_NS::type_of::nop_functor() BOOST_PP_INTERCEPT) ); + +// RP_GLOB_OPAQUE +// +// non-templated version for opaque rule parsers. +# define BOOST_SPIRIT_RP_GLOB_OPAQUE(name,name_t,np,pars) \ + static name_t const name = name_t () ; +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// PP_EMIT operations (fragment emittion based on array input) + +// - - Namespace handling + +// NS_OPEN +# define BOOST_SPIRIT_RP__NS_OPEN(r,data,i,elem) \ + namespace BOOST_SPIRIT_RP_OPTIONAL(elem) { + +// NS_QUALIFY +# define BOOST_SPIRIT_RP__NS_QUALIFY(r,data,i,elem) \ + BOOST_SPIRIT_RP_OPTIONAL(elem ::) + +// NS_CLOSE +# define BOOST_SPIRIT_RP__NS_CLOSE(r,data,i,elem) } + +// - - Parameter handling + +// PM_STATIC +# define BOOST_SPIRIT_RP__PM_STATIC(r,data,i,elem) \ + static typename ::boost::call_traits< data ## i >::reference elem ; + +// PM_CTOR_PARAMS +# define BOOST_SPIRIT_RP__PM_CTOR_PARAMS(r,data,i,elem) \ + BOOST_PP_COMMA_IF(i) \ + typename ::boost::call_traits< data ## i >::param_type elem + +// PM_CTOR_ARGS +# define BOOST_SPIRIT_RP__PM_CTOR_ARGS(r,data,i,elem) \ + BOOST_PP_COMMA_IF(i) elem + +// PM_CTOR_INIT_LIST +# define BOOST_SPIRIT_RP__PM_CTOR_INIT_LIST(r,data,i,elem) \ + BOOST_PP_COMMA_IF(i) __p ## i ( elem ) + +// PM_CTOR_COPY_INIT_LIST +# define BOOST_SPIRIT_RP__PM_CTOR_COPY_INIT_LIST(r,data,i,elem) \ + BOOST_PP_COMMA_IF(i) __p ## i ( that. __p ## i ) + + +// PM_TEMPLATE_PARAMS +# define BOOST_SPIRIT_RP__PM_TEMPLATE_PARAMS(r,data,i,elem) , data ## i + +// - strictly typed parameters of the opaque rule_parser + +// PM_OPAQUE_STATIC +# define BOOST_SPIRIT_RP__PM_OPAQUE_STATIC(r,data,i,elem) \ + static ::boost::call_traits< \ + BOOST_SPIRIT_RP_TYPE(BOOST_PP_TUPLE_ELEM(2,0,elem)) \ + >::reference BOOST_PP_TUPLE_ELEM(2,1,elem) ; + +// PM_OPAQUE_CTOR_PARAMS +# define BOOST_SPIRIT_RP__PM_OPAQUE_CTOR_PARAMS(r,data,i,elem) \ + BOOST_PP_COMMA_IF(i) ::boost::call_traits< \ + BOOST_SPIRIT_RP_TYPE(BOOST_PP_TUPLE_ELEM(2,0,elem)) \ + >::param_type BOOST_PP_TUPLE_ELEM(2,1,elem) + +// PM_OPAQUE_GEN_PARAMS +# define BOOST_SPIRIT_RP__PM_OPAQUE_GEN_PARAMS(r,data,i,elem) \ + BOOST_PP_COMMA_IF(i) ::boost::call_traits< \ + BOOST_SPIRIT_RP_TYPE(BOOST_PP_TUPLE_ELEM(2,0,elem)) \ + >::param_type data ## i + +// - - Member variable handling + +// MV_NONSTATIC +# define BOOST_SPIRIT_RP__MV_NONSTATIC(r,data,i,elem) \ + data() BOOST_SPIRIT_RP_TYPE(BOOST_PP_TUPLE_ELEM(3,0,elem)) \ + BOOST_PP_TUPLE_ELEM(3,1,elem) ; + +// MV_STATIC +# define BOOST_SPIRIT_RP__MV_STATIC(r,data,i,elem) \ + static data() ::boost::call_traits< \ + data() BOOST_SPIRIT_RP_TYPE(BOOST_PP_TUPLE_ELEM(3,0,elem)) \ + >::reference BOOST_PP_TUPLE_ELEM(3,1,elem) ; + +// MV_CTOR_INIT_LIST +# define BOOST_SPIRIT_RP__MV_CTOR_INIT_LIST(r,data,i,elem) \ + BOOST_PP_COMMA_IF(i) \ + BOOST_PP_TUPLE_ELEM(3,1,elem) BOOST_PP_TUPLE_ELEM(3,2,elem) + +// MV_CTOR_COPY_INIT_LIST +# define BOOST_SPIRIT_RP__MV_CTOR_COPY_INIT_LIST(r,data,i,elem) \ + BOOST_PP_COMMA_IF(i) \ + BOOST_PP_TUPLE_ELEM(3,1,elem) (data . BOOST_PP_TUPLE_ELEM(3,1,elem)) + +// - - Action placeholder handling + +// AP_STATIC +# define BOOST_SPIRIT_RP__AP_STATIC(r,data,i,elem) static __A ## i & elem ; + +// AP_CTOR_PARAMS +# define BOOST_SPIRIT_RP__AP_CTOR_PARAMS(r,data,i,elem) \ + BOOST_SPIRIT_RP_COMMA_IF_OR(data,i) \ + typename ::boost::call_traits< __A ## i >::param_type elem + +// AP_CTOR_ARGS +# define BOOST_SPIRIT_RP__AP_CTOR_ARGS(r,data,i,elem) \ + BOOST_SPIRIT_RP_COMMA_IF_OR(data,i) elem + +// AP_CTOR_INIT_LIST +# define BOOST_SPIRIT_RP__AP_CTOR_INIT_LIST(r,data,i,elem) \ + BOOST_SPIRIT_RP_COMMA_IF_OR(data,i) __a ## i ( elem ) + +// AP_CTOR_COPY_INIT_LIST +# define BOOST_SPIRIT_RP__AP_CTOR_COPY_INIT_LIST(r,data,i,elem) \ + BOOST_SPIRIT_RP_COMMA_IF_OR(data,i) __a ## i ( that. __a ## i ) + +// AP_TEMPLATE_PARAMS +# define BOOST_SPIRIT_RP__AP_TEMPLATE_PARAMS(r,data,i,elem) \ + , BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2,0,data),i) \ + BOOST_PP_EXPR_IIF(BOOST_PP_TUPLE_ELEM(2,1,data), \ + = ::BOOST_SPIRIT_CLASSIC_NS::type_of::nop_functor) + +// AP_REBOUND_ARGS +# define BOOST_SPIRIT_RP__AP_REBOUND_ARGS(r,data,i,elem) \ + BOOST_PP_COMMA_IF(i) \ + ::BOOST_SPIRIT_CLASSIC_NS::type_of::get_placeholdee< __action_placeholder:: elem > \ + ( __a ## i , data ) + +// AP_REBOUND_TPL_ARGS +# define BOOST_SPIRIT_RP__AP_REBOUND_TPL_ARGS(r,data,i,elem) \ + , typename ::BOOST_SPIRIT_CLASSIC_NS::type_of::placeholdee< \ + __action_placeholder:: elem , __A ## i, data >::type + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// PP_EMIT +// +// Performs one of the operations in the above section on an optional array. +// +# define BOOST_SPIRIT_RP_EMIT(op, array, data) \ + BOOST_SPIRIT_RP_ARRAY_FOR_EACH_I(BOOST_SPIRIT_RP__ ## op,data,array) +// --- --- - - --- - - --- - - - - --- - - - - - - - - - - - - - - - - - - - - - +// RP_ARRAY_FOR_EACH_I +// +// Iterates an optional array. That is you can pass e.g.'-' or 'none' to denote +// emptiness. +# define BOOST_SPIRIT_RP_ARRAY_FOR_EACH_I(macro,data,optional_array) \ + BOOST_PP_IIF(BOOST_PP_IS_BINARY(optional_array), \ + BOOST_SPIRIT_RP_ARRAY_FOR_EACH_I_IMPL, \ + BOOST_PP_TUPLE_EAT(3))(macro,data,optional_array) + +// RP_ARRAY_FOR_EACH_I_IMPL +# define BOOST_SPIRIT_RP_ARRAY_FOR_EACH_I_IMPL(macro,data,array) \ + BOOST_SPIRIT_RP_IF(BOOST_PP_ARRAY_SIZE(array),PP_SEQ_FOR_EACH_I,3) \ + (macro,data, BOOST_SPIRIT_RP_IF(BOOST_PP_ARRAY_SIZE(array), \ + PP_TUPLE_TO_SEQ,2) array) +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// RP_ARRAY_SIZE +// +// Expands to the size of an "optional array". +// +// Examples: +// +// BOOST_SPIRIT_RP_ARRAY_SIZE( (2,(a,b)) ) // 2 +// BOOST_SPIRIT_RP_ARRAY_SIZE( (0,()) ) // 0 +// BOOST_SPIRIT_RP_ARRAY_SIZE( none ) // 0 +// BOOST_SPIRIT_RP_ARRAY_SIZE( - ) // 0 +// +# define BOOST_SPIRIT_RP_ARRAY_SIZE(optional_array) \ + BOOST_PP_IIF(BOOST_PP_IS_BINARY(optional_array), \ + BOOST_PP_ARRAY_SIZE, 0 BOOST_PP_TUPLE_EAT(1))(optional_array) +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// RP_OPTIONAL +// +// Expands to nothing if the argument is parenthesized. +// +// Examples: +// +// BOOST_SPIRIT_RP_OPTIONAL( foobar ) // foobar +// BOOST_SPIRIT_RP_OPTIONAL( (none) ) // evaluates to nothing +// +# define BOOST_SPIRIT_RP_OPTIONAL(elem) \ + BOOST_PP_EXPR_IIF(BOOST_PP_COMPL(BOOST_PP_IS_UNARY(elem)),elem) +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// RP_COMMA_IF_OR +// +// Expands to nothing if both arguments are zero, otherwise expands to a comma. +// +# define BOOST_SPIRIT_RP_COMMA_IF_OR(a,b) \ + BOOST_PP_IIF(BOOST_PP_OR(a,b),BOOST_PP_COMMA,BOOST_PP_EMPTY)() +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// RP_IF +// +// BOOST_SPIRIT_RP_IF(cond,name,arity) +// +// is equivalent to: +// +// BOOST_PP_IF(cond,BOOST_name,BOOST_PP_TUPLE_EAT(arity)) +// +# define BOOST_SPIRIT_RP_IF(cond,name,arity) \ + BOOST_PP_IF(cond,BOOST_ ## name,BOOST_PP_TUPLE_EAT(arity)) + +//------------------------------------------------------------------------------ +// Wrapper and gernator function to embed a parser by reference +//------------------------------------------------------------------------------ + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + // Wrapper to embed a parser by reference + + template<class P> class parser_reference + : public parser< parser_reference<P> > + { + P const & ref_that; + public: + parser_reference(P & that) + // we allow implicit conversion but forbid temporaries. + : ref_that(that) + { } + + typedef parser_reference<P> self_t; + typedef self_t const & embed_t; + typedef typename P::parser_category_t parser_category_t; + + template<typename ScannerT> struct result + { typedef typename P::BOOST_NESTED_TEMPLATE result<ScannerT>::type type; }; + + template<typename ScannerT> + typename result<ScannerT>::type + parse(ScannerT const & scan) const + { return this->ref_that.parse(scan); } + }; + + template<class P> parser_reference<P> + embed_by_reference(::BOOST_SPIRIT_CLASSIC_NS::parser<P> & p) + { return p; } + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +} } // namespace ::BOOST_SPIRIT_CLASSIC_NS + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::parser_reference, 1) + +//------------------------------------------------------------------------------ +// Expression templates for action placeholders. +//------------------------------------------------------------------------------ + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +namespace type_of { + + // No-operation functor + + struct nop_functor + { + template<typename T> + bool operator()(T const &) const + { return false; } + template<typename T, typename U> + bool operator()(T const &, U const &) const + { return false; } + + typedef bool result_type; + }; + + // Composite action + + template<typename Action1, typename Action2> + class composite_action + { + Action1 fnc_a1; + Action2 fnc_a2; + public: + composite_action(Action1 const & a1, Action2 const & a2) + : fnc_a1(a1), fnc_a2(a2) + { } + + template<typename T> + void operator()(T const & inp) const + { fnc_a1(inp); fnc_a2(inp); } + + template<typename T, typename U> + void operator()(T const & inp1, U const inp2) const + { fnc_a1(inp1, inp2); fnc_a2(inp1, inp2); } + }; + + // Action concatenation (and optimize away nop_functorS) + + template<typename Action1, typename Action2> + struct action_concatenator + { + typedef composite_action<Action1,Action2> type; + + static type concatenate(Action1 const & a1, Action2 const & a2) + { return composite_action<Action1,Action2>(a1,a2); } + }; + template<typename Action> struct action_concatenator<nop_functor, Action> + { + typedef Action type; + + static type concatenate(nop_functor const &, Action const & a) + { return a; } + }; + template<typename Action> struct action_concatenator<Action, nop_functor> + { + typedef Action type; + + static type concatenate(Action const & a, nop_functor const &) + { return a; } + }; + template<> struct action_concatenator<nop_functor, nop_functor> + { + typedef nop_functor type; + + static type concatenate(nop_functor const &, nop_functor const &) + { return nop_functor(); } + }; + + template<typename Action1, typename Action2> + typename action_concatenator<Action1,Action2>::type + concatenate_actions(Action1 const & a1, Action2 const & a2) + { + return action_concatenator<Action1,Action2>::concatenate(a1,a2); + } + + // Action chains + + enum action_chain_mode { replace, append }; + + template<class Placeholder, action_chain_mode Mode, typename Action> + class action_chain + { + Action fnc_action; + public: + action_chain(Action const & a) + : fnc_action(a) + { } + + typedef Action action_type; + + Action const & action() const { return fnc_action; } + }; + + // This operator adds actions to an action chain definition + template<class PH, action_chain_mode M, typename A1, typename A2> + action_chain<PH, M, typename action_concatenator<A1,A2>::type> + operator, (action_chain<PH,M,A1> const & chain, A2 const & a) + { + return action_chain<PH,M,typename action_concatenator<A1,A2>::type> + ( concatenate_actions(chain.action(), a) ); + } + + // Expression template for mutiple action chain assignments + template<class ChainOrChains, class LastChain> + class action_chains + { + ChainOrChains obj_head; + LastChain obj_tail; + public: + action_chains(ChainOrChains const & head, LastChain const & tail) + : obj_head(head), obj_tail(tail) + { } + + typedef ChainOrChains head_type; + typedef LastChain tail_type; + + head_type const & head() const { return obj_head; } + tail_type const & tail() const { return obj_tail; } + }; + + // Action chain concatenation + template<class Head, class Tail> + action_chains<Head,Tail> make_chain(Head const & h, Tail const & t) + { return action_chains<Head,Tail>(h,t); } + + template<class PH1, action_chain_mode M1, typename A1, + class PH2, action_chain_mode M2, typename A2> + action_chains< action_chain<PH1,M1,A1>, action_chain<PH2,M2,A2> > + operator, (action_chain<PH1,M1,A1> const & h, + action_chain<PH2,M2,A2> const & t) + { return make_chain(h,t); } + + template<class Head, class Tail,class PH, action_chain_mode M, typename A> + action_chains< action_chains<Head,Tail>, action_chain<PH,M,A> > + operator, (action_chains<Head,Tail> const & h, action_chain<PH,M,A> const & t) + { return make_chain(h,t); } + + + // Extract the (maybe composite) action associated with an action + // placeholders from the chains with a fold algorithm. + template<class Placeholder, typename StartAction, class NewChainOrChains> + struct placeholdee + { + typedef StartAction type; + + static type get(StartAction const & a, NewChainOrChains const &) + { return a; } + }; + + template<class Placeholder, // <-- non-deduced + typename StartAction, class NewChainOrChains> + typename placeholdee<Placeholder,StartAction,NewChainOrChains>::type + get_placeholdee(StartAction const & a, NewChainOrChains const & c) + { return placeholdee<Placeholder,StartAction,NewChainOrChains>::get(a,c); } + + template<class Placeholder, typename StartAction, class Head, class Tail> + struct placeholdee + < Placeholder, StartAction, action_chains<Head,Tail> > + { + typedef typename placeholdee<Placeholder, + typename placeholdee<Placeholder,StartAction,Head>::type, Tail >::type + type; + + static type get(StartAction const & a, action_chains<Head,Tail> const & c) + { + return get_placeholdee<Placeholder>( + get_placeholdee<Placeholder>(a,c.head()), c.tail() ); + } + }; + + template<class Placeholder, typename StartAction, typename A> + struct placeholdee + < Placeholder, StartAction, action_chain<Placeholder,replace,A> > + { + typedef A type; + + static type get(StartAction const &, + action_chain<Placeholder,replace,A> const & c) + { return c.action(); } + }; + + template<class Placeholder, typename StartAction, typename A> + struct placeholdee + < Placeholder, StartAction, action_chain<Placeholder,append,A> > + { + typedef typename action_concatenator<StartAction,A>::type type; + + static type get(StartAction const & a, + action_chain<Placeholder,append,A> const & c) + { return concatenate_actions(a,c.action()); } + }; + +} + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +} } // namespace ::BOOST_SPIRIT_CLASSIC_NS::type_of + +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::type_of::nop_functor) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::type_of::composite_action,2) + +//------------------------------------------------------------------------------ +// Misc.utilities +//------------------------------------------------------------------------------ + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +namespace type_of { + + // Utility function to create a dependency to a template argument. + + template<typename T, typename X> + X const & depend_on_type(X const & x) + { return x; } + + // Utility to allow use parenthesized type expressions with commas inside + // as a type within macros. Thanks to Dave Abrahams for telling me this nice + // trick. + + #define BOOST_SPIRIT_RP_TYPE(x) \ + ::BOOST_SPIRIT_CLASSIC_NS::type_of::remove_special_fptr \ + < ::BOOST_SPIRIT_CLASSIC_NS::type_of::special_result & (*) x >::type + + struct special_result; + + template<typename T> struct remove_special_fptr { }; + template<typename T> struct remove_special_fptr< special_result & (*)(T) > + { typedef T type; }; + +} + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +} } // namespace ::BOOST_SPIRIT_CLASSIC_NS::type_of + +//------------------------------------------------------------------------------ +#endif +//------------------------------------------------------------------------------ + diff --git a/boost/spirit/home/classic/utility/scoped_lock.hpp b/boost/spirit/home/classic/utility/scoped_lock.hpp new file mode 100644 index 0000000000..952fd8785e --- /dev/null +++ b/boost/spirit/home/classic/utility/scoped_lock.hpp @@ -0,0 +1,112 @@ +/*============================================================================= + Copyright (c) 2003 Martin Wille + 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_UTILITY_SCOPED_LOCK_HPP +#define BOOST_SPIRIT_UTILITY_SCOPED_LOCK_HPP + +/////////////////////////////////////////////////////////////////////////////// +#include <boost/spirit/home/classic/namespace.hpp> +#if !defined(BOOST_SPIRIT_COMPOSITE_HPP) +#include <boost/spirit/home/classic/core/composite.hpp> +#endif + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // scoped_lock_parser class + // + // implements locking of a mutex during execution of + // the parse method of an embedded parser + // + /////////////////////////////////////////////////////////////////////////// + template <typename MutexT, typename ParserT> + struct scoped_lock_parser + : public unary< ParserT, parser< scoped_lock_parser<MutexT, ParserT> > > + { + typedef scoped_lock_parser<MutexT, ParserT> self_t; + typedef MutexT mutex_t; + typedef ParserT parser_t; + + template <typename ScannerT> + struct result + { + typedef typename parser_result<parser_t, ScannerT>::type type; + }; + + scoped_lock_parser(mutex_t &m, parser_t const &p) + : unary< ParserT, parser< scoped_lock_parser<MutexT, ParserT> > >(p) + , mutex(m) + {} + + + template <typename ScannerT> + typename parser_result<self_t, ScannerT>::type + parse(ScannerT const &scan) const + { + typedef typename mutex_t::scoped_lock scoped_lock_t; + scoped_lock_t lock(mutex); + return this->subject().parse(scan); + } + + mutex_t &mutex; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // scoped_lock_parser_gen + // + // generator for scoped_lock_parser objects + // operator[] returns scoped_lock_parser according to its argument + // + /////////////////////////////////////////////////////////////////////////// + template <typename MutexT> + struct scoped_lock_parser_gen + { + typedef MutexT mutex_t; + explicit scoped_lock_parser_gen(mutex_t &m) : mutex(m) {} + + template<typename ParserT> + scoped_lock_parser + < + MutexT, + typename as_parser<ParserT>::type + > + operator[](ParserT const &p) const + { + typedef ::BOOST_SPIRIT_CLASSIC_NS::as_parser<ParserT> as_parser_t; + typedef typename as_parser_t::type parser_t; + + return scoped_lock_parser<mutex_t, parser_t> + (mutex, as_parser_t::convert(p)); + } + + mutex_t &mutex; + }; + + + /////////////////////////////////////////////////////////////////////////// + // + // scoped_lock_d parser directive + // + // constructs a scoped_lock_parser generator from its argument + // + /////////////////////////////////////////////////////////////////////////// + template <typename MutexT> + scoped_lock_parser_gen<MutexT> + scoped_lock_d(MutexT &mutex) + { + return scoped_lock_parser_gen<MutexT>(mutex); + } + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS +#endif // BOOST_SPIRIT_UTILITY_SCOPED_LOCK_HPP diff --git a/boost/spirit/home/classic/utility/typeof.hpp b/boost/spirit/home/classic/utility/typeof.hpp new file mode 100644 index 0000000000..9c70619b52 --- /dev/null +++ b/boost/spirit/home/classic/utility/typeof.hpp @@ -0,0 +1,150 @@ +/*============================================================================= + Copyright (c) 2006 Tobias Schwinger + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_UTILITY_TYPEOF_HPP) +#define BOOST_SPIRIT_UTILITY_TYPEOF_HPP + +#include <boost/typeof/typeof.hpp> + +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/typeof.hpp> + +#include <boost/spirit/home/classic/utility/escape_char_fwd.hpp> +#include <boost/spirit/home/classic/utility/confix_fwd.hpp> +#include <boost/spirit/home/classic/utility/lists_fwd.hpp> +#include <boost/spirit/home/classic/utility/distinct_fwd.hpp> +#include <boost/spirit/home/classic/utility/grammar_def_fwd.hpp> + +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + // chset.hpp + template<typename CharT> class chset; + + // functor_parser.hpp + template<typename FunctorT> struct functor_parser; + + // loops.hpp + template<class ParserT, typename ExactT> class fixed_loop; + template<class ParserT, typename MinT, typename MaxT> class finite_loop; + template<class ParserT, typename MinT> class infinite_loop; + + // regex.hpp + template<typename CharT> struct rxstrlit; + + // flush_multi_pass.hpp + class flush_multi_pass_parser; + + // scoped_lock.hpp + template<class MutexT, class ParserT> struct scoped_lock_parser; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + + +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() + + +// chset.hpp + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::chset,1) + +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::chset<char>) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::chset<wchar_t>) + + +// escape_char.hpp (has forward header) + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::escape_char_parser,(BOOST_TYPEOF_INTEGRAL(unsigned long))(typename)) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::escape_char_action,(class)(typename)(BOOST_TYPEOF_INTEGRAL(unsigned long))(typename)) + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::escape_char_parser,(BOOST_TYPEOF_INTEGRAL(unsigned long))) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::escape_char_action,(class)(typename)(BOOST_TYPEOF_INTEGRAL(unsigned long))) + + +// functor_parser.hpp + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::functor_parser,1) + + +// loops.hpp + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::fixed_loop,2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::finite_loop,3) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::infinite_loop,2) + + +// regex.hpp + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::rxstrlit,1) + +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::rxstrlit<char>) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::rxstrlit<wchar_t>) + + +// confix.hpp (has forward header) + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::confix_parser, 6) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::confix_parser, 5) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::confix_parser, 4) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::confix_parser, 3) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::comment_nest_parser, 2) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::is_nested) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::non_nested) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::is_lexeme) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::non_lexeme) + + +// lists.hpp (has forward header) + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::list_parser,4) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::list_parser,3) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::list_parser,2) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::no_list_endtoken) + + +// distinct.hpp (has forward header) + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::distinct_parser,2) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::distinct_parser,1) +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::dynamic_distinct_parser,1) +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::distinct_parser<>) + + +// flush_multi_pass.hpp + +BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::flush_multi_pass_parser) + + +// scoped_lock.hpp + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::scoped_lock_parser,2) + + +// grammar_gen.hpp (has forward header) + +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::grammar_def,BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT) + +#if BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT > 12 +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::grammar_def,12) +#endif +#if BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT > 9 +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::grammar_def, 9) +#endif +#if BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT > 6 +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::grammar_def, 6) +#endif +#if BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT > 3 +BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::grammar_def, 3) +#endif + + +#endif + + diff --git a/boost/spirit/home/classic/version.hpp b/boost/spirit/home/classic/version.hpp new file mode 100644 index 0000000000..77371ed37c --- /dev/null +++ b/boost/spirit/home/classic/version.hpp @@ -0,0 +1,30 @@ +/*============================================================================= + Copyright (c) 2001-2003 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(SPIRIT_CLASSIC_VERSION_HPP) +#define SPIRIT_CLASSIC_VERSION_HPP + +/////////////////////////////////////////////////////////////////////////////// +// +// This checks, whether the used Boost library is at least V1.32.0 +// +/////////////////////////////////////////////////////////////////////////////// +#include <boost/version.hpp> + +#if BOOST_VERSION < 103200 +#error "Spirit v1.8.x needs at least Boost V1.32.0 to compile successfully." +#endif + +/////////////////////////////////////////////////////////////////////////////// +// +// This is the version of the current Spirit distribution +// +/////////////////////////////////////////////////////////////////////////////// +#define SPIRIT_VERSION 0x1806 +#define SPIRIT_PIZZA_VERSION SPIRIT_MEGA_VEGGI // :-) + +#endif // defined(SPIRIT_VERSION_HPP) |