code:
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
// Copyright (C) 2009 Sebastian Redl
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------

#ifndef BOOST_PROPERTY_TREE_PTREE_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_PTREE_HPP_INCLUDED

#include <boost/property_tree/ptree_fwd.hpp>
#include <boost/property_tree/string_path.hpp>
#include <boost/property_tree/stream_translator.hpp>
#include <boost/property_tree/exceptions.hpp>
#include <boost/property_tree/detail/ptree_utils.hpp>

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/indexed_by.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/throw_exception.hpp>
#include <boost/optional.hpp>
#include <utility>                  // for std::pair

namespace boost { namespace property_tree
{

    /**
     * Property tree main structure. A property tree is a hierarchical data
     * structure which has one element of type @p Data in each node, as well
     * as an ordered sequence of sub-nodes, which are additionally identified
     * by a non-unique key of type @p Key.
     *
     * Key equivalency is defined by @p KeyCompare, a predicate defining a
     * strict weak ordering.
     *
     * Property tree defines a Container-like interface to the (key-node) pairs
     * of its direct sub-nodes. The iterators are bidirectional. The sequence
     * of nodes is held in insertion order, not key order.
     */
    template<class Key, class Data, class KeyCompare>
    class basic_ptree
    {
#if defined(BOOST_PROPERTY_TREE_DOXYGEN_INVOKED)
    public:
#endif
        // Internal types
        /**
         * Simpler way to refer to this basic_ptree\<C,K,P,A\> type.
         * Note that this is private, and made public only for doxygen.
         */
        typedef basic_ptree<Key, Data, KeyCompare> self_type;

    public:
        // Basic types
        typedef Key                                  key_type;
        typedef Data                                 data_type;
        typedef KeyCompare                           key_compare;

        // Container view types
        typedef std::pair<const Key, self_type>      value_type;
        typedef std::size_t                          size_type;

        // The problem with the iterators is that I can't make them complete
        // until the container is complete. Sucks. Especially for the reverses.
        class iterator;
        class const_iterator;
        class reverse_iterator;
        class const_reverse_iterator;

        // Associative view types
        class assoc_iterator;
        class const_assoc_iterator;

        // Property tree view types
        typedef typename path_of<Key>::type          path_type;

        // The big five

        /** Creates a node with no children and default-constructed data. */
        basic_ptree();
        /** Creates a node with no children and a copy of the given data. */
        explicit basic_ptree(const data_type &data);
        basic_ptree(const self_type &rhs);
        ~basic_ptree();
        /** Basic guarantee only. */
        self_type &operator =(const self_type &rhs);

        /** Swap with other tree. Only constant-time and nothrow if the
         * data type's swap is.
         */
        void swap(self_type &rhs);

        // Container view functions

        /** The number of direct children of this node. */
        size_type size() const;
        size_type max_size() const;
        /** Whether there are any direct children. */
        bool empty() const;

        iterator begin();
        const_iterator begin() const;
        iterator end();
        const_iterator end() const;
        reverse_iterator rbegin();
        const_reverse_iterator rbegin() const;
        reverse_iterator rend();
        const_reverse_iterator rend() const;

        value_type &front();
        const value_type &front() const;
        value_type &back();
        const value_type &back() const;

        /** Insert a copy of the given tree with its key just before the given
         * position in this node. This operation invalidates no iterators.
         * @return An iterator to the newly created child.
         */
        iterator insert(iterator where, const value_type &value);

        /** Range insert. Equivalent to:
         * @code
         * for(; first != last; ++first) insert(where, *first);
         * @endcode
         */
        template<class It> void insert(iterator where, It first, It last);

        /** Erase the child pointed at by the iterator. This operation
         * invalidates the given iterator, as well as its equivalent
         * assoc_iterator.
         * @return A valid iterator pointing to the element after the erased.
         */
        iterator erase(iterator where);

        /** Range erase. Equivalent to:
         * @code
         * while(first != last;) first = erase(first);
         * @endcode
         */
        iterator erase(iterator first, iterator last);

        /** Equivalent to insert(begin(), value). */
        iterator push_front(const value_type &value);

        /** Equivalent to insert(end(), value). */
        iterator push_back(const value_type &value);

        /** Equivalent to erase(begin()). */
        void pop_front();

        /** Equivalent to erase(boost::prior(end())). */
        void pop_back();

        /** Reverses the order of direct children in the property tree. */
        void reverse();

        /** Sorts the direct children of this node according to the predicate.
         * The predicate is passed the whole pair of key and child.
         */
        template<class Compare> void sort(Compare comp);

        /** Sorts the direct children of this node according to key order. */
        void sort();

        // Equality

        /** Two property trees are the same if they have the same data, the keys
         * and order of their children are the same, and the children compare
         * equal, recursively.
         */
        bool operator ==(const self_type &rhs) const;
        bool operator !=(const self_type &rhs) const;

        // Associative view

        /** Returns an iterator to the first child, in key order. */
        assoc_iterator ordered_begin();
        /** Returns an iterator to the first child, in key order. */
        const_assoc_iterator ordered_begin() const;

        /** Returns the not-found iterator. Equivalent to end() in a real
         * associative container.
         */
        assoc_iterator not_found();
        /** Returns the not-found iterator. Equivalent to end() in a real
         * associative container.
         */
        const_assoc_iterator not_found() const;

        /** Find a child with the given key, or not_found() if there is none.
         * There is no guarantee about which child is returned if multiple have
         * the same key.
         */
        assoc_iterator find(const key_type &key);

        /** Find a child with the given key, or not_found() if there is none.
         * There is no guarantee about which child is returned if multiple have
         * the same key.
         */
        const_assoc_iterator find(const key_type &key) const;

        /** Find the range of children that have the given key. */
        std::pair<assoc_iterator, assoc_iterator>
            equal_range(const key_type &key);

        /** Find the range of children that have the given key. */
        std::pair<const_assoc_iterator, const_assoc_iterator>
            equal_range(const key_type &key) const;

        /** Count the number of direct children with the given key. */
        size_type count(const key_type &key) const;

        /** Erase all direct children with the given key and return the count.
         */
        size_type erase(const key_type &key);

        /** Get the iterator that points to the same element as the argument.
         * @note A valid assoc_iterator range (a, b) does not imply that
         *       (to_iterator(a), to_iterator(b)) is a valid range.
         */
        iterator to_iterator(assoc_iterator it);

        /** Get the iterator that points to the same element as the argument.
         * @note A valid const_assoc_iterator range (a, b) does not imply that
         *       (to_iterator(a), to_iterator(b)) is a valid range.
         */
        const_iterator to_iterator(const_assoc_iterator it) const;

        // Property tree view

        /** Reference to the actual data in this node. */
        data_type &data();

        /** Reference to the actual data in this node. */
        const data_type &data() const;

        /** Clear this tree completely, of both data and children. */
        void clear();

        /** Get the child at the given path, or throw @c ptree_bad_path.
         * @note Depending on the path, the result at each level may not be
         *       completely deterministic, i.e. if the same key appears multiple
         *       times, which child is chosen is not specified. This can lead
         *       to the path not being resolved even though there is a
         *       descendant with this path. Example:
         * @code
         *   a -> b -> c
         *     -> b
         * @endcode
         *       The path "a.b.c" will succeed if the resolution of "b" chooses
         *       the first such node, but fail if it chooses the second.
         */
        self_type &get_child(const path_type &path);

        /** Get the child at the given path, or throw @c ptree_bad_path. */
        const self_type &get_child(const path_type &path) const;

        /** Get the child at the given path, or return @p default_value. */
        self_type &get_child(const path_type &path, self_type &default_value);

        /** Get the child at the given path, or return @p default_value. */
        const self_type &get_child(const path_type &path,
                                   const self_type &default_value) const;

        /** Get the child at the given path, or return boost::null. */
        optional<self_type &> get_child_optional(const path_type &path);

        /** Get the child at the given path, or return boost::null. */
        optional<const self_type &>
          get_child_optional(const path_type &path) const;

        /** Set the node at the given path to the given value. Create any
         * missing parents. If the node at the path already exists, replace it.
         * @return A reference to the inserted subtree.
         * @note Because of the way paths work, it is not generally guaranteed
         *       that a node newly created can be accessed using the same path.
         * @note If the path could refer to multiple nodes, it is unspecified
         *       which one gets replaced.
         */
        self_type &put_child(const path_type &path, const self_type &value);

        /** Add the node at the given path. Create any missing parents. If there
         * already is a node at the path, add another one with the same key.
         * @param path Path to the child. The last fragment must not have an
         *             index.
         * @return A reference to the inserted subtree.
         * @note Because of the way paths work, it is not generally guaranteed
         *       that a node newly created can be accessed using the same path.
         */
        self_type &add_child(const path_type &path, const self_type &value);

        /** Take the value of this node and attempt to translate it to a
         * @c Type object using the supplied translator.
         * @throw ptree_bad_data if the conversion fails.
         */
        template<class Type, class Translator>
        typename boost::enable_if<detail::is_translator<Translator>, Type>::type
        get_value(Translator tr) const;

        /** Take the value of this node and attempt to translate it to a
         * @c Type object using the default translator.
         * @throw ptree_bad_data if the conversion fails.
         */
        template<class Type>
        Type get_value() const;

        /** Take the value of this node and attempt to translate it to a
         * @c Type object using the supplied translator. Return @p default_value
         * if this fails.
         */
        template<class Type, class Translator>
        Type get_value(const Type &default_value, Translator tr) const;

        /** Make get_value do the right thing for string literals. */
        template <class Ch, class Translator>
        typename boost::enable_if<
            detail::is_character<Ch>,
            std::basic_string<Ch>
        >::type
        get_value(const Ch *default_value, Translator tr) const;

        /** Take the value of this node and attempt to translate it to a
         * @c Type object using the default translator. Return @p default_value
         * if this fails.
         */
        template<class Type>
        typename boost::disable_if<detail::is_translator<Type>, Type>::type
        get_value(const Type &default_value) const;

        /** Make get_value do the right thing for string literals. */
        template <class Ch>
        typename boost::enable_if<
            detail::is_character<Ch>,
            std::basic_string<Ch>
        >::type
        get_value(const Ch *default_value) const;

        /** Take the value of this node and attempt to translate it to a
         * @c Type object using the supplied translator. Return boost::null if
         * this fails.
         */
        template<class Type, class Translator>
        optional<Type> get_value_optional(Translator tr) const;

        /** Take the value of this node and attempt to translate it to a
         * @c Type object using the default translator. Return boost::null if
         * this fails.
         */
        template<class Type>
        optional<Type> get_value_optional() const;

        /** Replace the value at this node with the given value, translated
         * to the tree's data type using the supplied translator.
         * @throw ptree_bad_data if the conversion fails.
        */
        template<class Type, class Translator>
        void put_value(const Type &value, Translator tr);

        /** Replace the value at this node with the given value, translated
         * to the tree's data type using the default translator.
         * @throw ptree_bad_data if the conversion fails.
        */
        template<class Type>
        void put_value(const Type &value);

        /** Shorthand for get_child(path).get_value(tr). */
        template<class Type, class Translator>
        typename boost::enable_if<detail::is_translator<Translator>, Type>::type
        get(const path_type &path, Translator tr) const;

        /** Shorthand for get_child(path).get_value\<Type\>(). */
        template<class Type>
        Type get(const path_type &path) const;

        /** Shorthand for get_child(path, empty_ptree())
         *                    .get_value(default_value, tr).
         * That is, return the translated value if possible, and the default
         * value if the node doesn't exist or conversion fails.
         */
        template<class Type, class Translator>
        Type get(const path_type &path,
                 const Type &default_value,
                 Translator tr) const;

        /** Make get do the right thing for string literals. */
        template <class Ch, class Translator>
        typename boost::enable_if<
            detail::is_character<Ch>,
            std::basic_string<Ch>
        >::type
        get(const path_type &path, const Ch *default_value, Translator tr)const;

        /** Shorthand for get_child(path, empty_ptree())
         *                    .get_value(default_value).
         * That is, return the translated value if possible, and the default
         * value if the node doesn't exist or conversion fails.
         */
        template<class Type>
        typename boost::disable_if<detail::is_translator<Type>, Type>::type
        get(const path_type &path, const Type &default_value) const;

        /** Make get do the right thing for string literals. */
        template <class Ch>
        typename boost::enable_if<
            detail::is_character<Ch>,
            std::basic_string<Ch>
        >::type
        get(const path_type &path, const Ch *default_value) const;

        /** Shorthand for:
         * @code
         * if(optional\<self_type&\> node = get_child_optional(path))
         *   return node->get_value_optional(tr);
         * return boost::null;
         * @endcode
         * That is, return the value if it exists and can be converted, or nil.
        */
        template<class Type, class Translator>
        optional<Type> get_optional(const path_type &path, Translator tr) const;

        /** Shorthand for:
         * @code
         * if(optional\<const self_type&\> node = get_child_optional(path))
         *   return node->get_value_optional();
         * return boost::null;
         * @endcode
         * That is, return the value if it exists and can be converted, or nil.
        */
        template<class Type>
        optional<Type> get_optional(const path_type &path) const;

        /** Set the value of the node at the given path to the supplied value,
         * translated to the tree's data type. If the node doesn't exist, it is
         * created, including all its missing parents.
         * @return The node that had its value changed.
         * @throw ptree_bad_data if the conversion fails.
        */
        template<class Type, class Translator>
        self_type &put(const path_type &path, const Type &value, Translator tr);

        /** Set the value of the node at the given path to the supplied value,
         * translated to the tree's data type. If the node doesn't exist, it is
         * created, including all its missing parents.
         * @return The node that had its value changed.
         * @throw ptree_bad_data if the conversion fails.
        */
        template<class Type>
        self_type &put(const path_type &path, const Type &value);

        /** If the node identified by the path does not exist, create it,
         * including all its missing parents.
         * If the node already exists, add a sibling with the same key.
         * Set the newly created node's value to the given paremeter,
         * translated with the supplied translator.
         * @param path Path to the child. The last fragment must not have an
         *             index.
         * @param value The value to add.
         * @param tr The translator to use.
         * @return The node that was added.
         * @throw ptree_bad_data if the conversion fails.
        */
        template<class Type, class Translator>
        self_type &add(const path_type &path,
                       const Type &value,
                       Translator tr);

        /** If the node identified by the path does not exist, create it,
         * including all its missing parents.
         * If the node already exists, add a sibling with the same key.
         * Set the newly created node's value to the given paremeter,
         * translated with the supplied translator.
         * @param path Path to the child. The last fragment must not have an
         *             index.
         * @param value The value to add.
         * @return The node that was added.
         * @throw ptree_bad_data if the conversion fails.
        */
        template<class Type>
        self_type &add(const path_type &path, const Type &value);

    private:
        // Hold the data of this node
        data_type m_data;
        // Hold the children - this is a void* because we can't complete the
        // container type within the class.
        void* m_children;

        // Getter tree-walk. Not const-safe! Gets the node the path refers to,
        // or null. Destroys p's value.
        self_type* walk_path(path_type& p) const;

        // Modifer tree-walk. Gets the parent of the node referred to by the
        // path, creating nodes as necessary. p is the path to the remaining
        // child.
        self_type& force_path(path_type& p);

        // This struct contains typedefs for the concrete types.
        struct subs;
        friend struct subs;
        friend class iterator;
        friend class const_iterator;
        friend class reverse_iterator;
        friend class const_reverse_iterator;
    };

}}

#include <boost/property_tree/detail/ptree_implementation.hpp>

#endif


code:
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
// Copyright (C) 2009 Sebastian Redl
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#ifndef BOOST_PROPERTY_TREE_PTREE_FWD_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_PTREE_FWD_HPP_INCLUDED

#include <boost/config.hpp>
#include <boost/optional/optional_fwd.hpp>
#include <boost/throw_exception.hpp>
#include <functional>           // for std::less
#include <memory>               // for std::allocator
#include <string>

namespace boost { namespace property_tree
{
    namespace detail {
        template <typename T> struct less_nocase;
    }

    // Classes

    template < class Key, class Data, class KeyCompare = std::less<Key> >
    class basic_ptree;

    template <typename T>
    struct id_translator;

    template <typename String, typename Translator>
    class string_path;

    // Texas-style concepts for documentation only.
#if 0
    concept PropertyTreePath<class Path> {
        // The key type for which this path works.
        typename key_type;
        // Return the key that the first segment of the path names.
        // Split the head off the state.
        key_type Path::reduce();

        // Return true if the path is empty.
        bool Path::empty() const;

        // Return true if the path contains a single element.
        bool Path::single() const;

        // Dump as a std::string, for exception messages.
        std::string Path::dump() const;
    }
    concept PropertyTreeKey<class Key> {
        PropertyTreePath path;
        requires SameType<Key, PropertyTreePath<path>::key_type>;
    }
    concept PropertyTreeTranslator<class Tr> {
        typename internal_type;
        typename external_type;

        boost::optional<external_type> Tr::get_value(internal_type);
        boost::optional<internal_type> Tr::put_value(external_type);
    }
#endif
    /// If you want to use a custom key type, specialize this struct for it
    /// and give it a 'type' typedef that specifies your path type. The path
    /// type must conform to the Path concept described in the documentation.
    /// This is already specialized for std::basic_string.
    template <typename Key>
    struct path_of;

    /// Specialize this struct to specify a default translator between the data
    /// in a tree whose data_type is Internal, and the external data_type
    /// specified in a get_value, get, put_value or put operation.
    /// This is already specialized for Internal being std::basic_string.
    template <typename Internal, typename External>
    struct translator_between;

    class ptree_error;
    class ptree_bad_data;
    class ptree_bad_path;

    // Typedefs

    /** Implements a path using a std::string as the key. */
    typedef string_path<std::string, id_translator<std::string> > path;

    /**
     * A property tree with std::string for key and data, and default
     * comparison.
     */
    typedef basic_ptree<std::string, std::string> ptree;

    /**
     * A property tree with std::string for key and data, and case-insensitive
     * comparison.
     */
    typedef basic_ptree<std::string, std::string,
                        detail::less_nocase<std::string> >
        iptree;

#ifndef BOOST_NO_STD_WSTRING
    /** Implements a path using a std::wstring as the key. */
    typedef string_path<std::wstring, id_translator<std::wstring> > wpath;

    /**
     * A property tree with std::wstring for key and data, and default
     * comparison.
     * @note The type only exists if the platform supports @c wchar_t.
     */
    typedef basic_ptree<std::wstring, std::wstring> wptree;

    /**
     * A property tree with std::wstring for key and data, and case-insensitive
     * comparison.
     * @note The type only exists if the platform supports @c wchar_t.
     */
    typedef basic_ptree<std::wstring, std::wstring,
                        detail::less_nocase<std::wstring> >
        wiptree;
#endif

    // Free functions

    /**
     * Swap two property tree instances.
     */
    template<class K, class D, class C>
    void swap(basic_ptree<K, D, C> &pt1,
              basic_ptree<K, D, C> &pt2);

} }

#if !defined(BOOST_PROPERTY_TREE_DOXYGEN_INVOKED)
    // Throwing macro to avoid no return warnings portably
#   define BOOST_PROPERTY_TREE_THROW(e) BOOST_THROW_EXCEPTION(e)
#endif

#endif

license: mit


code:
// ----------------------------------------------------------------------------
// Copyright (C) 2009 Sebastian Redl
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------

#ifndef BOOST_PROPERTY_TREE_STREAM_TRANSLATOR_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_STREAM_TRANSLATOR_HPP_INCLUDED

#include <boost/property_tree/ptree_fwd.hpp>

#include <boost/optional.hpp>
#include <boost/optional/optional_io.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/decay.hpp>
#include <boost/type_traits/integral_constant.hpp>
#include <sstream>
#include <string>
#include <locale>
#include <limits>

namespace boost { namespace property_tree
{

    template <typename Ch, typename Traits, typename E, typename Enabler = void>
    struct customize_stream
    {
        static void insert(std::basic_ostream<Ch, Traits>& s, const E& e) {
            s << e;
        }
        static void extract(std::basic_istream<Ch, Traits>& s, E& e) {
            s >> e;
            if(!s.eof()) {
                s >> std::ws;
            }
        }
    };

    // No whitespace skipping for single characters.
    template <typename Ch, typename Traits>
    struct customize_stream<Ch, Traits, Ch, void>
    {
        static void insert(std::basic_ostream<Ch, Traits>& s, Ch e) {
            s << e;
        }
        static void extract(std::basic_istream<Ch, Traits>& s, Ch& e) {
            s.unsetf(std::ios_base::skipws);
            s >> e;
        }
    };

    // Ugly workaround for numeric_traits that don't have members when not
    // specialized, e.g. MSVC.
    namespace detail
    {
        template <bool is_specialized>
        struct is_inexact_impl
        {
            template <typename T>
            struct test
            {
                typedef boost::false_type type;
            };
        };
        template <>
        struct is_inexact_impl<true>
        {
            template <typename T>
            struct test
            {
              typedef boost::integral_constant<bool,
                  !std::numeric_limits<T>::is_exact> type;
            };
        };

        template <typename F>
        struct is_inexact
        {
            typedef typename boost::decay<F>::type decayed;
            typedef typename is_inexact_impl<
                std::numeric_limits<decayed>::is_specialized
            >::BOOST_NESTED_TEMPLATE test<decayed>::type type;
            static const bool value = type::value;
        };
    }

    template <typename Ch, typename Traits, typename F>
    struct customize_stream<Ch, Traits, F,
        typename boost::enable_if< detail::is_inexact<F> >::type
    >
    {
        static void insert(std::basic_ostream<Ch, Traits>& s, const F& e) {
#ifndef BOOST_NO_CXX11_NUMERIC_LIMITS
            s.precision(std::numeric_limits<F>::max_digits10);
#else
            s.precision(std::numeric_limits<F>::digits10 + 2);
#endif
            s << e;
        }
        static void extract(std::basic_istream<Ch, Traits>& s, F& e) {
            s >> e;
            if(!s.eof()) {
                s >> std::ws;
            }
        }
    };

    template <typename Ch, typename Traits>
    struct customize_stream<Ch, Traits, bool, void>
    {
        static void insert(std::basic_ostream<Ch, Traits>& s, bool e) {
            s.setf(std::ios_base::boolalpha);
            s << e;
        }
        static void extract(std::basic_istream<Ch, Traits>& s, bool& e) {
            s >> e;
            if(s.fail()) {
                // Try again in word form.
                s.clear();
                s.setf(std::ios_base::boolalpha);
                s >> e;
            }
            if(!s.eof()) {
                s >> std::ws;
            }
        }
    };

    template <typename Ch, typename Traits>
    struct customize_stream<Ch, Traits, signed char, void>
    {
        static void insert(std::basic_ostream<Ch, Traits>& s, signed char e) {
            s << (int)e;
        }
        static void extract(std::basic_istream<Ch, Traits>& s, signed char& e) {
            int i;
            s >> i;
            // out of range?
            if(i > (std::numeric_limits<signed char>::max)() ||
                i < (std::numeric_limits<signed char>::min)())
            {
                s.clear(); // guarantees eof to be unset
                e = 0;
                s.setstate(std::ios_base::badbit);
                return;
            }
            e = (signed char)i;
            if(!s.eof()) {
                s >> std::ws;
            }
        }
    };

    template <typename Ch, typename Traits>
    struct customize_stream<Ch, Traits, unsigned char, void>
    {
        static void insert(std::basic_ostream<Ch, Traits>& s, unsigned char e) {
            s << (unsigned)e;
        }
        static void extract(std::basic_istream<Ch,Traits>& s, unsigned char& e){
            unsigned i;
            s >> i;
            // out of range?
            if(i > (std::numeric_limits<unsigned char>::max)()) {
                s.clear(); // guarantees eof to be unset
                e = 0;
                s.setstate(std::ios_base::badbit);
                return;
            }
            e = (unsigned char)i;
            if(!s.eof()) {
                s >> std::ws;
            }
        }
    };

    /// Implementation of Translator that uses the stream overloads.
    template <typename Ch, typename Traits, typename Alloc, typename E>
    class stream_translator
    {
        typedef customize_stream<Ch, Traits, E> customized;
    public:
        typedef std::basic_string<Ch, Traits, Alloc> internal_type;
        typedef E external_type;

        explicit stream_translator(std::locale loc = std::locale())
            : m_loc(loc)
        {}

        boost::optional<E> get_value(const internal_type &v) {
            std::basic_istringstream<Ch, Traits, Alloc> iss(v);
            iss.imbue(m_loc);
            E e;
            customized::extract(iss, e);
            if(iss.fail() || iss.bad() || iss.get() != Traits::eof()) {
                return boost::optional<E>();
            }
            return e;
        }
        boost::optional<internal_type> put_value(const E &v) {
            std::basic_ostringstream<Ch, Traits, Alloc> oss;
            oss.imbue(m_loc);
            customized::insert(oss, v);
            if(oss) {
                return oss.str();
            }
            return boost::optional<internal_type>();
        }

    private:
        std::locale m_loc;
    };

    // This is the default translator when basic_string is the internal type.
    // Unless the external type is also basic_string, in which case
    // id_translator takes over.
    template <typename Ch, typename Traits, typename Alloc, typename E>
    struct translator_between<std::basic_string<Ch, Traits, Alloc>, E>
    {
        typedef stream_translator<Ch, Traits, Alloc, E> type;
    };

}}

#endif


code:
// ----------------------------------------------------------------------------
// Copyright (C) 2009 Sebastian Redl
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------

#ifndef BOOST_PROPERTY_TREE_STRING_PATH_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_STRING_PATH_HPP_INCLUDED

#include <boost/property_tree/ptree_fwd.hpp>
#include <boost/property_tree/id_translator.hpp>
#include <boost/property_tree/exceptions.hpp>
#include <boost/property_tree/detail/ptree_utils.hpp>

#include <boost/static_assert.hpp>
#include <boost/assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/optional.hpp>
#include <boost/throw_exception.hpp>
#include <algorithm>
#include <string>
#include <iterator>

namespace boost { namespace property_tree
{
    namespace detail
    {
        template <typename Sequence, typename Iterator>
        void append_and_preserve_iter(Sequence &s, const Sequence &r,
                                      Iterator &, std::forward_iterator_tag)
        {
            // Here we boldly assume that anything that is not random-access
            // preserves validity. This is valid for the STL sequences.
            s.insert(s.end(), r.begin(), r.end());
        }
        template <typename Sequence, typename Iterator>
        void append_and_preserve_iter(Sequence &s, const Sequence &r,
                                      Iterator &it,
                                      std::random_access_iterator_tag)
        {
            // Convert the iterator to an index, and later back.
            typename std::iterator_traits<Iterator>::difference_type idx =
                it - s.begin();
            s.insert(s.end(), r.begin(), r.end());
            it = s.begin() + idx;
        }

        template <typename Sequence>
        inline std::string dump_sequence(const Sequence &)
        {
            return "<undumpable sequence>";
        }
        inline std::string dump_sequence(const std::string &s)
        {
            return s;
        }
#ifndef BOOST_NO_STD_WSTRING
        inline std::string dump_sequence(const std::wstring &s)
        {
            return narrow<std::string>(s.c_str());
        }
#endif
    }

    /// Default path class. A path is a sequence of values. Groups of values
    /// are separated by the separator value, which defaults to '.' cast to
    /// the sequence's value type. The group of values is then passed to the
    /// translator to get a key.
    ///
    /// If instantiated with std::string and id_translator\<std::string\>,
    /// it accepts paths of the form "one.two.three.four".
    ///
    /// @tparam String Any Sequence. If the sequence does not support random-
    ///                access iteration, concatenation of paths assumes that
    ///                insertions at the end preserve iterator validity.
    /// @tparam Translator A translator with internal_type == String.
    template <typename String, typename Translator>
    class string_path
    {
        BOOST_STATIC_ASSERT((is_same<String,
                                   typename Translator::internal_type>::value));
    public:
        typedef typename Translator::external_type key_type;
        typedef typename String::value_type char_type;

        /// Create an empty path.
        explicit string_path(char_type separator = char_type('.'));
        /// Create a path by parsing the given string.
        /// @param value A sequence, possibly with separators, that describes
        ///              the path, e.g. "one.two.three".
        /// @param separator The separator used in parsing. Defaults to '.'.
        /// @param tr The translator used by this path to convert the individual
        ///           parts to keys.
        string_path(const String &value, char_type separator = char_type('.'),
                    Translator tr = Translator());
        /// Create a path by parsing the given string.
        /// @param value A zero-terminated array of values. Only use if zero-
        ///              termination makes sense for your type, and your
        ///              sequence supports construction from it. Intended for
        ///              string literals.
        /// @param separator The separator used in parsing. Defaults to '.'.
        /// @param tr The translator used by this path to convert the individual
        ///           parts to keys.
        string_path(const char_type *value,
                    char_type separator = char_type('.'),
                    Translator tr = Translator());

        // Default copying doesn't do the right thing with the iterator
        string_path(const string_path &o);
        string_path& operator =(const string_path &o);

        /// Take a single element off the path at the front and return it.
        key_type reduce();

        /// Test if the path is empty.
        bool empty() const;

        /// Test if the path contains a single element, i.e. no separators.
        bool single() const;

        /// Get the separator used by this path.
        char_type separator() const { return m_separator; }

        std::string dump() const {
            return detail::dump_sequence(m_value);
        }

        /// Append a second path to this one.
        /// @pre o's separator is the same as this one's, or o has no separators
        string_path& operator /=(const string_path &o) {
            // If it's single, there's no separator. This allows to do
            // p /= "piece";
            // even for non-default separators.
            BOOST_ASSERT((m_separator == o.m_separator
                          || o.empty()
                          || o.single())
                         && "Incompatible paths.");
            if(!o.empty()) {
                String sub;
                if(!this->empty()) {
                    sub.push_back(m_separator);
                }
                sub.insert(sub.end(), o.cstart(), o.m_value.end());
                detail::append_and_preserve_iter(m_value, sub, m_start,
                    typename std::iterator_traits<s_iter>::iterator_category());
            }
            return *this;
        }

    private:
        typedef typename String::iterator s_iter;
        typedef typename String::const_iterator s_c_iter;
        String m_value;
        char_type m_separator;
        Translator m_tr;
        s_iter m_start;
        s_c_iter cstart() const { return m_start; }
    };

    template <typename String, typename Translator> inline
    string_path<String, Translator>::string_path(char_type separator)
        : m_separator(separator), m_start(m_value.begin())
    {}

    template <typename String, typename Translator> inline
    string_path<String, Translator>::string_path(const String &value,
                                                 char_type separator,
                                                 Translator tr)
        : m_value(value), m_separator(separator),
          m_tr(tr), m_start(m_value.begin())
    {}

    template <typename String, typename Translator> inline
    string_path<String, Translator>::string_path(const char_type *value,
                                                 char_type separator,
                                                 Translator tr)
        : m_value(value), m_separator(separator),
          m_tr(tr), m_start(m_value.begin())
    {}

    template <typename String, typename Translator> inline
    string_path<String, Translator>::string_path(const string_path &o)
        : m_value(o.m_value), m_separator(o.m_separator),
          m_tr(o.m_tr), m_start(m_value.begin())
    {
        std::advance(m_start, std::distance(o.m_value.begin(), o.cstart()));
    }

    template <typename String, typename Translator> inline
    string_path<String, Translator>&
    string_path<String, Translator>::operator =(const string_path &o)
    {
        m_value = o.m_value;
        m_separator = o.m_separator;
        m_tr = o.m_tr;
        m_start = m_value.begin();
        std::advance(m_start, std::distance(o.m_value.begin(), o.cstart()));
        return *this;
    }

    template <typename String, typename Translator>
    typename Translator::external_type string_path<String, Translator>::reduce()
    {
        BOOST_ASSERT(!empty() && "Reducing empty path");

        s_iter next_sep = std::find(m_start, m_value.end(), m_separator);
        String part(m_start, next_sep);
        m_start = next_sep;
        if(!empty()) {
          // Unless we're at the end, skip the separator we found.
          ++m_start;
        }

        if(optional<key_type> key = m_tr.get_value(part)) {
            return *key;
        }
        BOOST_PROPERTY_TREE_THROW(ptree_bad_path("Path syntax error", *this));
    }

    template <typename String, typename Translator> inline
    bool string_path<String, Translator>::empty() const
    {
        return m_start == m_value.end();
    }

    template <typename String, typename Translator> inline
    bool string_path<String, Translator>::single() const
    {
        return std::find(static_cast<s_c_iter>(m_start),
                         m_value.end(), m_separator)
            == m_value.end();
    }

    // By default, this is the path for strings. You can override this by
    // specializing path_of for a more specific form of std::basic_string.
    template <typename Ch, typename Traits, typename Alloc>
    struct path_of< std::basic_string<Ch, Traits, Alloc> >
    {
        typedef std::basic_string<Ch, Traits, Alloc> _string;
        typedef string_path< _string, id_translator<_string> > type;
    };

    template <typename String, typename Translator> inline
    string_path<String, Translator> operator /(
                                  string_path<String, Translator> p1,
                                  const string_path<String, Translator> &p2)
    {
        p1 /= p2;
        return p1;
    }

    // These shouldn't be necessary, but GCC won't find the one above.
    template <typename String, typename Translator> inline
    string_path<String, Translator> operator /(
                                  string_path<String, Translator> p1,
                                  const typename String::value_type *p2)
    {
        p1 /= p2;
        return p1;
    }

    template <typename String, typename Translator> inline
    string_path<String, Translator> operator /(
                                  const typename String::value_type *p1,
                                  const string_path<String, Translator> &p2)
    {
        string_path<String, Translator> t(p1);
        t /= p2;
        return t;
    }

}}

#endif


code:
///////////////////////////////////////////////////////////////////////////////
/// \file args.hpp
/// Contains definition of \c term\<\>, \c list1\<\>, \c list2\<\>, ...
/// class templates.
//
//  Copyright 2008 Eric Niebler. Distributed under the Boost
//  Software License, Version 1.0. (See accompanying file
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_PROTO_ARGS_HPP_EAN_04_01_2005
#define BOOST_PROTO_ARGS_HPP_EAN_04_01_2005

#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/arithmetic/dec.hpp>
#include <boost/preprocessor/iteration/iterate.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/void.hpp>
#include <boost/proto/proto_fwd.hpp>
#include <boost/proto/detail/is_noncopyable.hpp>

#include <boost/mpl/or.hpp>
#include <boost/type_traits/is_function.hpp>
#include <boost/type_traits/is_abstract.hpp>

namespace boost { namespace proto
{
    namespace detail
    {
        /// INTERNAL ONLY
        template<typename Expr>
        struct expr_traits
        {
            typedef Expr value_type;
            typedef Expr &reference;
            typedef Expr const &const_reference;
        };

        /// INTERNAL ONLY
        template<typename Expr>
        struct expr_traits<Expr &>
        {
            typedef Expr value_type;
            typedef Expr &reference;
            typedef Expr &const_reference;
        };

        /// INTERNAL ONLY
        template<typename Expr>
        struct expr_traits<Expr const &>
        {
            typedef Expr value_type;
            typedef Expr const &reference;
            typedef Expr const &const_reference;
        };

        /// INTERNAL ONLY
        template<typename T>
        struct term_traits
        {
            typedef T value_type;
            typedef T &reference;
            typedef T const &const_reference;
        };

        /// INTERNAL ONLY
        template<typename T>
        struct term_traits<T &>
        {
            typedef typename mpl::if_c<is_noncopyable<T>::value, T &, T>::type value_type;
            typedef T &reference;
            typedef T &const_reference;
        };

        /// INTERNAL ONLY
        template<typename T>
        struct term_traits<T const &>
        {
            typedef T value_type;
            typedef T const &reference;
            typedef T const &const_reference;
        };

        /// INTERNAL ONLY
        template<typename T, std::size_t N>
        struct term_traits<T (&)[N]>
        {
            typedef T value_type[N];
            typedef T (&reference)[N];
            typedef T (&const_reference)[N];
        };

        /// INTERNAL ONLY
        template<typename T, std::size_t N>
        struct term_traits<T const (&)[N]>
        {
            typedef T value_type[N];
            typedef T const (&reference)[N];
            typedef T const (&const_reference)[N];
        };

        /// INTERNAL ONLY
        template<typename T, std::size_t N>
        struct term_traits<T[N]>
        {
            typedef T value_type[N];
            typedef T (&reference)[N];
            typedef T const (&const_reference)[N];
        };

        /// INTERNAL ONLY
        template<typename T, std::size_t N>
        struct term_traits<T const[N]>
        {
            typedef T value_type[N];
            typedef T const (&reference)[N];
            typedef T const (&const_reference)[N];
        };
    }

    namespace argsns_
    {
        // This is where term and all the different listN templates are defined
        #include <boost/proto/detail/args.hpp>
    }

}}

#endif


code:
///////////////////////////////////////////////////////////////////////////////
/// \file context.hpp
/// Includes all the context classes in the context/ sub-directory.
//
//  Copyright 2008 Eric Niebler. Distributed under the Boost
//  Software License, Version 1.0. (See accompanying file
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_PROTO_CONTEXT_HPP_EAN_06_23_2007
#define BOOST_PROTO_CONTEXT_HPP_EAN_06_23_2007

#include <boost/proto/context/null.hpp>
#include <boost/proto/context/default.hpp>
#include <boost/proto/context/callable.hpp>

#endif


code:
///////////////////////////////////////////////////////////////////////////////
/// \file callable.hpp
/// Definintion of callable_context\<\>, an evaluation context for
/// proto::eval() that explodes each node and calls the derived context
/// type with the expressions constituents. If the derived context doesn't
/// have an overload that handles this node, fall back to some other
/// context.
//
//  Copyright 2008 Eric Niebler. Distributed under the Boost
//  Software License, Version 1.0. (See accompanying file
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_PROTO_CONTEXT_CALLABLE_HPP_EAN_06_23_2007
#define BOOST_PROTO_CONTEXT_CALLABLE_HPP_EAN_06_23_2007

#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/iteration/iterate.hpp>
#include <boost/preprocessor/facilities/intercept.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_trailing.hpp>
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
#include <boost/preprocessor/arithmetic/inc.hpp>
#include <boost/preprocessor/selection/max.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/utility/result_of.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/proto/proto_fwd.hpp>
#include <boost/proto/traits.hpp> // for child_c

namespace boost { namespace proto
{
    namespace detail
    {
        template<typename Context>
        struct callable_context_wrapper
          : remove_cv<Context>::type
        {
            callable_context_wrapper();
            typedef private_type_ fun_type(...);
            operator fun_type *() const;
        private:
            callable_context_wrapper &operator =(callable_context_wrapper const &);
        };

        template<typename T>
        yes_type check_is_expr_handled(T const &);

        no_type check_is_expr_handled(private_type_ const &);

        template<typename Expr, typename Context, long Arity = Expr::proto_arity_c>
        struct is_expr_handled;

        template<typename Expr, typename Context>
        struct is_expr_handled<Expr, Context, 0>
        {
            static callable_context_wrapper<Context> &sctx_;
            static Expr &sexpr_;
            static typename Expr::proto_tag &stag_;

            static const bool value =
                sizeof(yes_type) ==
                sizeof(
                    detail::check_is_expr_handled(
                        (sctx_(stag_, proto::value(sexpr_)), 0)
                    )
                );

            typedef mpl::bool_<value> type;
        };
    }

    namespace context
    {
        /// \brief A BinaryFunction that accepts a Proto expression and a
        /// callable context and calls the context with the expression tag
        /// and children as arguments, effectively fanning the expression
        /// out.
        ///
        /// <tt>callable_eval\<\></tt> requires that \c Context is a
        /// PolymorphicFunctionObject that can be invoked with \c Expr's
        /// tag and children as expressions, as follows:
        ///
        /// \code
        /// context(Expr::proto_tag(), child_c<0>(expr), child_c<1>(expr), ...)
        /// \endcode
        template<
            typename Expr
          , typename Context
          , long Arity          // = Expr::proto_arity_c
        >
        struct callable_eval
        {};

        /// \brief A BinaryFunction that accepts a Proto expression and a
        /// callable context and calls the context with the expression tag
        /// and children as arguments, effectively fanning the expression
        /// out.
        ///
        /// <tt>callable_eval\<\></tt> requires that \c Context is a
        /// PolymorphicFunctionObject that can be invoked with \c Expr's
        /// tag and children as expressions, as follows:
        ///
        /// \code
        /// context(Expr::proto_tag(), value(expr))
        /// \endcode
        template<typename Expr, typename Context>
        struct callable_eval<Expr, Context, 0>
        {
            typedef typename proto::result_of::value<Expr const &>::type value_type;

            typedef
                typename BOOST_PROTO_RESULT_OF<
                    Context(typename Expr::proto_tag, value_type)
                >::type
            result_type;

            /// \param expr The current expression
            /// \param context The callable evaluation context
            /// \return <tt>context(Expr::proto_tag(), value(expr))</tt>
            result_type operator ()(Expr &expr, Context &context) const
            {
                return context(typename Expr::proto_tag(), proto::value(expr));
            }
        };

        /// \brief An evaluation context adaptor that makes authoring a
        /// context a simple matter of writing function overloads, rather
        /// then writing template specializations.
        ///
        /// <tt>callable_context\<\></tt> is a base class that implements
        /// the context protocol by passing fanned-out expression nodes to
        /// the derived context, making it easy to customize the handling
        /// of expression types by writing function overloads. Only those
        /// expression types needing special handling require explicit
        /// handling. All others are dispatched to a user-specified
        /// default context, \c DefaultCtx.
        ///
        /// <tt>callable_context\<\></tt> is defined simply as:
        ///
        /// \code
        /// template<typename Context, typename DefaultCtx = default_context>
        /// struct callable_context
        /// {
        ///    template<typename Expr, typename ThisContext = Context>
        ///     struct eval
        ///       : mpl::if_<
        ///             is_expr_handled_<Expr, Context> // For exposition
        ///           , callable_eval<Expr, ThisContext>
        ///           , typename DefaultCtx::template eval<Expr, Context>
        ///         >::type
        ///     {};
        /// };
        /// \endcode
        ///
        /// The Boolean metafunction <tt>is_expr_handled_\<\></tt> uses
        /// metaprogramming tricks to determine whether \c Context has
        /// an overloaded function call operator that accepts the
        /// fanned-out constituents of an expression of type \c Expr.
        /// If so, the handling of the expression is dispatched to
        /// <tt>callable_eval\<\></tt>. If not, it is dispatched to
        /// the user-specified \c DefaultCtx.
        ///
        /// Below is an example of how to use <tt>callable_context\<\></tt>:
        ///
        /// \code
        /// // An evaluation context that increments all
        /// // integer terminals in-place.
        /// struct increment_ints
        ///  : callable_context<
        ///         increment_ints const    // derived context
        ///       , null_context const      // fall-back context
        ///     >
        /// {
        ///     typedef void result_type;
        ///
        ///     // Handle int terminals here:
        ///     void operator()(proto::tag::terminal, int &i) const
        ///     {
        ///        ++i;
        ///     }
        /// };
        /// \endcode
        ///
        /// With \c increment_ints, we can do the following:
        ///
        /// \code
        /// literal<int> i = 0, j = 10;
        /// proto::eval( i - j * 3.14, increment_ints() );
        ///
        /// assert( i.get() == 1 && j.get() == 11 );
        /// \endcode
        template<
            typename Context
          , typename DefaultCtx // = default_context
        >
        struct callable_context
        {
            /// A BinaryFunction that accepts an \c Expr and a
            /// \c Context, and either fans out the expression and passes
            /// it to the context, or else hands off the expression to
            /// \c DefaultCtx.
            ///
            /// If \c Context is a PolymorphicFunctionObject such that
            /// it can be invoked with the tag and children of \c Expr,
            /// as <tt>ctx(Expr::proto_tag(), child_c\<0\>(expr), child_c\<1\>(expr)...)</tt>,
            /// then <tt>eval\<Expr, ThisContext\></tt> inherits from
            /// <tt>callable_eval\<Expr, ThisContext\></tt>. Otherwise,
            /// <tt>eval\<Expr, ThisContext\></tt> inherits from
            /// <tt>DefaultCtx::eval\<Expr, Context\></tt>.
            template<typename Expr, typename ThisContext = Context>
            struct eval
              : mpl::if_c<
                    detail::is_expr_handled<Expr, Context>::value
                  , callable_eval<Expr, ThisContext>
                  , typename DefaultCtx::template eval<Expr, Context>
                >::type
            {};
        };
    }

    #include <boost/proto/context/detail/callable_eval.hpp>

}}

#endif


code:
///////////////////////////////////////////////////////////////////////////////
/// \file default.hpp
/// Definintion of default_context, a default evaluation context for
/// proto::eval() that uses Boost.Typeof to deduce return types
/// of the built-in operators.
//
//  Copyright 2008 Eric Niebler. Distributed under the Boost
//  Software License, Version 1.0. (See accompanying file
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_PROTO_CONTEXT_DEFAULT_HPP_EAN_01_08_2007
#define BOOST_PROTO_CONTEXT_DEFAULT_HPP_EAN_01_08_2007

#include <boost/config.hpp>
#include <boost/preprocessor/arithmetic/add.hpp>
#include <boost/preprocessor/arithmetic/sub.hpp>
#include <boost/preprocessor/iteration/iterate.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_shifted.hpp>
#include <boost/utility/result_of.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/is_function.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/is_member_pointer.hpp>
#include <boost/type_traits/is_member_object_pointer.hpp>
#include <boost/type_traits/is_member_function_pointer.hpp>
#include <boost/proto/proto_fwd.hpp>
#include <boost/proto/tags.hpp>
#include <boost/proto/eval.hpp>
#include <boost/proto/traits.hpp> // for proto::child_c()
#include <boost/proto/detail/decltype.hpp>

namespace boost { namespace proto
{
/// INTERNAL ONLY
///
#define UNREF(x) typename boost::remove_reference<x>::type

    namespace context
    {
        template<
            typename Expr
          , typename Context
          , typename Tag        // = typename Expr::proto_tag
          , long Arity          // = Expr::proto_arity_c
        >
        struct default_eval
        {};

        template<typename Expr, typename Context>
        struct default_eval<Expr, Context, tag::terminal, 0>
        {
            typedef
                typename proto::result_of::value<Expr &>::type
            result_type;

            result_type operator ()(Expr &expr, Context &) const
            {
                return proto::value(expr);
            }
        };

        /// INTERNAL ONLY
        ///
    #define BOOST_PROTO_UNARY_DEFAULT_EVAL(OP, TAG, MAKE)                                       \
        template<typename Expr, typename Context>                                               \
        struct default_eval<Expr, Context, TAG, 1>                                              \
        {                                                                                \
        private:                                                                                \
            typedef typename proto::result_of::child_c<Expr, 0>::type e0;                       \
            typedef typename proto::result_of::eval<UNREF(e0), Context>::type r0;               \
        public:                                                                                \
            BOOST_PROTO_DECLTYPE_(OP proto::detail::MAKE<r0>(), result_type)                    \
            result_type operator ()(Expr &expr, Context &ctx) const                             \
            {                                                                                \
                return OP proto::eval(proto::child_c<0>(expr), ctx);                            \
            }                                                                                \
        };                                                                                \
        /**/

        /// INTERNAL ONLY
        ///
    #define BOOST_PROTO_BINARY_DEFAULT_EVAL(OP, TAG, LMAKE, RMAKE)                              \
        template<typename Expr, typename Context>                                               \
        struct default_eval<Expr, Context, TAG, 2>                                              \
        {                                                                                \
        private:                                                                                \
            typedef typename proto::result_of::child_c<Expr, 0>::type e0;                       \
            typedef typename proto::result_of::child_c<Expr, 1>::type e1;                       \
            typedef typename proto::result_of::eval<UNREF(e0), Context>::type r0;               \
            typedef typename proto::result_of::eval<UNREF(e1), Context>::type r1;               \
        public:                                                                                \
            BOOST_PROTO_DECLTYPE_(                                                              \
                proto::detail::LMAKE<r0>() OP proto::detail::RMAKE<r1>()                        \
              , result_type                                                                     \
            )                                                                                \
            result_type operator ()(Expr &expr, Context &ctx) const                             \
            {                                                                                \
                return proto::eval(                                                             \
                    proto::child_c<0>(expr), ctx) OP proto::eval(proto::child_c<1>(expr)        \
                  , ctx                                                                         \
                );                                                                              \
            }                                                                                \
        };                                                                                \
        /**/

        BOOST_PROTO_UNARY_DEFAULT_EVAL(+, proto::tag::unary_plus, make)
        BOOST_PROTO_UNARY_DEFAULT_EVAL(-, proto::tag::negate, make)
        BOOST_PROTO_UNARY_DEFAULT_EVAL(*, proto::tag::dereference, make)
        BOOST_PROTO_UNARY_DEFAULT_EVAL(~, proto::tag::complement, make)
        BOOST_PROTO_UNARY_DEFAULT_EVAL(&, proto::tag::address_of, make)
        BOOST_PROTO_UNARY_DEFAULT_EVAL(!, proto::tag::logical_not, make)
        BOOST_PROTO_UNARY_DEFAULT_EVAL(++, proto::tag::pre_inc, make_mutable)
        BOOST_PROTO_UNARY_DEFAULT_EVAL(--, proto::tag::pre_dec, make_mutable)

        BOOST_PROTO_BINARY_DEFAULT_EVAL(<<, proto::tag::shift_left, make_mutable, make)
        BOOST_PROTO_BINARY_DEFAULT_EVAL(>>, proto::tag::shift_right, make_mutable, make)
        BOOST_PROTO_BINARY_DEFAULT_EVAL(*, proto::tag::multiplies, make, make)
        BOOST_PROTO_BINARY_DEFAULT_EVAL(/, proto::tag::divides, make, make)
        BOOST_PROTO_BINARY_DEFAULT_EVAL(%, proto::tag::modulus, make, make)
        BOOST_PROTO_BINARY_DEFAULT_EVAL(+, proto::tag::plus, make, make)
        BOOST_PROTO_BINARY_DEFAULT_EVAL(-, proto::tag::minus, make, make)
        BOOST_PROTO_BINARY_DEFAULT_EVAL(<, proto::tag::less, make, make)
        BOOST_PROTO_BINARY_DEFAULT_EVAL(>, proto::tag::greater, make, make)
        BOOST_PROTO_BINARY_DEFAULT_EVAL(<=, proto::tag::less_equal, make, make)
        BOOST_PROTO_BINARY_DEFAULT_EVAL(>=, proto::tag::greater_equal, make, make)
        BOOST_PROTO_BINARY_DEFAULT_EVAL(==, proto::tag::equal_to, make, make)
        BOOST_PROTO_BINARY_DEFAULT_EVAL(!=, proto::tag::not_equal_to, make, make)
        BOOST_PROTO_BINARY_DEFAULT_EVAL(||, proto::tag::logical_or, make, make)
        BOOST_PROTO_BINARY_DEFAULT_EVAL(&&, proto::tag::logical_and, make, make)
        BOOST_PROTO_BINARY_DEFAULT_EVAL(&, proto::tag::bitwise_and, make, make)
        BOOST_PROTO_BINARY_DEFAULT_EVAL(|, proto::tag::bitwise_or, make, make)
        BOOST_PROTO_BINARY_DEFAULT_EVAL(^, proto::tag::bitwise_xor, make, make)

        BOOST_PROTO_BINARY_DEFAULT_EVAL(=, proto::tag::assign, make_mutable, make)
        BOOST_PROTO_BINARY_DEFAULT_EVAL(<<=, proto::tag::shift_left_assign, make_mutable, make)
        BOOST_PROTO_BINARY_DEFAULT_EVAL(>>=, proto::tag::shift_right_assign, make_mutable, make)
        BOOST_PROTO_BINARY_DEFAULT_EVAL(*=, proto::tag::multiplies_assign, make_mutable, make)
        BOOST_PROTO_BINARY_DEFAULT_EVAL(/=, proto::tag::divides_assign, make_mutable, make)
        BOOST_PROTO_BINARY_DEFAULT_EVAL(%=, proto::tag::modulus_assign, make_mutable, make)
        BOOST_PROTO_BINARY_DEFAULT_EVAL(+=, proto::tag::plus_assign, make_mutable, make)
        BOOST_PROTO_BINARY_DEFAULT_EVAL(-=, proto::tag::minus_assign, make_mutable, make)
        BOOST_PROTO_BINARY_DEFAULT_EVAL(&=, proto::tag::bitwise_and_assign, make_mutable, make)
        BOOST_PROTO_BINARY_DEFAULT_EVAL(|=, proto::tag::bitwise_or_assign, make_mutable, make)
        BOOST_PROTO_BINARY_DEFAULT_EVAL(^=, proto::tag::bitwise_xor_assign, make_mutable, make)

    #undef BOOST_PROTO_UNARY_DEFAULT_EVAL
    #undef BOOST_PROTO_BINARY_DEFAULT_EVAL

        /// INTERNAL ONLY
        template<typename Expr, typename Context>
        struct is_member_function_eval
          : is_member_function_pointer<
                typename detail::uncvref<
                    typename proto::result_of::eval<
                        typename remove_reference<
                            typename proto::result_of::child_c<Expr, 1>::type
                        >::type
                      , Context
                    >::type
                >::type
            >
        {};

        /// INTERNAL ONLY
        template<typename Expr, typename Context, bool IsMemFunCall>
        struct memfun_eval
        {
        private:
            typedef typename result_of::child_c<Expr, 0>::type e0;
            typedef typename result_of::child_c<Expr, 1>::type e1;
            typedef typename proto::result_of::eval<UNREF(e0), Context>::type r0;
            typedef typename proto::result_of::eval<UNREF(e1), Context>::type r1;
        public:
            typedef typename detail::mem_ptr_fun<r0, r1>::result_type result_type;
            result_type operator ()(Expr &expr, Context &ctx) const
            {
                return detail::mem_ptr_fun<r0, r1>()(
                    proto::eval(proto::child_c<0>(expr), ctx)
                  , proto::eval(proto::child_c<1>(expr), ctx)
                );
            }
        };

        /// INTERNAL ONLY
        template<typename Expr, typename Context>
        struct memfun_eval<Expr, Context, true>
        {
        private:
            typedef typename result_of::child_c<Expr, 0>::type e0;
            typedef typename result_of::child_c<Expr, 1>::type e1;
            typedef typename proto::result_of::eval<UNREF(e0), Context>::type r0;
            typedef typename proto::result_of::eval<UNREF(e1), Context>::type r1;
        public:
            typedef detail::memfun<r0, r1> result_type;
            result_type const operator ()(Expr &expr, Context &ctx) const
            {
                return detail::memfun<r0, r1>(
                    proto::eval(proto::child_c<0>(expr), ctx)
                  , proto::eval(proto::child_c<1>(expr), ctx)
                );
            }
        };

        template<typename Expr, typename Context>
        struct default_eval<Expr, Context, tag::mem_ptr, 2>
          : memfun_eval<Expr, Context, is_member_function_eval<Expr, Context>::value>
        {};

        // Handle post-increment specially.
        template<typename Expr, typename Context>
        struct default_eval<Expr, Context, proto::tag::post_inc, 1>
        {
        private:
            typedef typename proto::result_of::child_c<Expr, 0>::type e0;
            typedef typename proto::result_of::eval<UNREF(e0), Context>::type r0;
        public:
            BOOST_PROTO_DECLTYPE_(proto::detail::make_mutable<r0>() ++, result_type)
            result_type operator ()(Expr &expr, Context &ctx) const
            {
                return proto::eval(proto::child_c<0>(expr), ctx) ++;
            }
        };

        // Handle post-decrement specially.
        template<typename Expr, typename Context>
        struct default_eval<Expr, Context, proto::tag::post_dec, 1>
        {
        private:
            typedef typename proto::result_of::child_c<Expr, 0>::type e0;
            typedef typename proto::result_of::eval<UNREF(e0), Context>::type r0;
        public:
            BOOST_PROTO_DECLTYPE_(proto::detail::make_mutable<r0>() --, result_type)
            result_type operator ()(Expr &expr, Context &ctx) const
            {
                return proto::eval(proto::child_c<0>(expr), ctx) --;
            }
        };

        // Handle subscript specially.
        template<typename Expr, typename Context>
        struct default_eval<Expr, Context, proto::tag::subscript, 2>
        {
        private:
            typedef typename proto::result_of::child_c<Expr, 0>::type e0;
            typedef typename proto::result_of::child_c<Expr, 1>::type e1;
            typedef typename proto::result_of::eval<UNREF(e0), Context>::type r0;
            typedef typename proto::result_of::eval<UNREF(e1), Context>::type r1;
        public:
            BOOST_PROTO_DECLTYPE_(proto::detail::make_subscriptable<r0>()[proto::detail::make<r1>()], result_type)
            result_type operator ()(Expr &expr, Context &ctx) const
            {
                return proto::eval(proto::child_c<0>(expr), ctx)[proto::eval(proto::child_c<1>(expr), ctx)];
            }
        };

        // Handle if_else_ specially.
        template<typename Expr, typename Context>
        struct default_eval<Expr, Context, proto::tag::if_else_, 3>
        {
        private:
            typedef typename proto::result_of::child_c<Expr, 0>::type e0;
            typedef typename proto::result_of::child_c<Expr, 1>::type e1;
            typedef typename proto::result_of::child_c<Expr, 2>::type e2;
            typedef typename proto::result_of::eval<UNREF(e0), Context>::type r0;
            typedef typename proto::result_of::eval<UNREF(e1), Context>::type r1;
            typedef typename proto::result_of::eval<UNREF(e2), Context>::type r2;
        public:
            BOOST_PROTO_DECLTYPE_(
                proto::detail::make<r0>()
              ? proto::detail::make<r1>()
              : proto::detail::make<r2>()
              , result_type
            )
            result_type operator ()(Expr &expr, Context &ctx) const
            {
                return proto::eval(proto::child_c<0>(expr), ctx)
                      ? proto::eval(proto::child_c<1>(expr), ctx)
                      : proto::eval(proto::child_c<2>(expr), ctx);
            }
        };

        // Handle comma specially.
        template<typename Expr, typename Context>
        struct default_eval<Expr, Context, proto::tag::comma, 2>
        {
        private:
            typedef typename proto::result_of::child_c<Expr, 0>::type e0;
            typedef typename proto::result_of::child_c<Expr, 1>::type e1;
            typedef typename proto::result_of::eval<UNREF(e0), Context>::type r0;
            typedef typename proto::result_of::eval<UNREF(e1), Context>::type r1;
        public:
            typedef typename proto::detail::comma_result<r0, r1>::type result_type;
            result_type operator ()(Expr &expr, Context &ctx) const
            {
                return proto::eval(proto::child_c<0>(expr), ctx), proto::eval(proto::child_c<1>(expr), ctx);
            }
        };

        // Handle function specially
        #define BOOST_PROTO_DEFAULT_EVAL_TYPE(Z, N, DATA)                                       \
            typename proto::result_of::eval<                                                    \
                typename remove_reference<                                                      \
                    typename proto::result_of::child_c<DATA, N>::type                           \
                >::type                                                                         \
              , Context                                                                         \
            >::type                                                                             \
            /**/

        #define BOOST_PROTO_DEFAULT_EVAL(Z, N, DATA)                                            \
            proto::eval(proto::child_c<N>(DATA), context)                                       \
            /**/

        template<typename Expr, typename Context>
        struct default_eval<Expr, Context, proto::tag::function, 1>
        {
            typedef
                typename proto::detail::result_of_fixup<
                    BOOST_PROTO_DEFAULT_EVAL_TYPE(~, 0, Expr)
                >::type
            function_type;

            typedef
                typename BOOST_PROTO_RESULT_OF<function_type()>::type
            result_type;

            result_type operator ()(Expr &expr, Context &context) const
            {
                return BOOST_PROTO_DEFAULT_EVAL(~, 0, expr)();
            }
        };

        template<typename Expr, typename Context>
        struct default_eval<Expr, Context, proto::tag::function, 2>
        {
            typedef
                typename proto::detail::result_of_fixup<
                    BOOST_PROTO_DEFAULT_EVAL_TYPE(~, 0, Expr)
                >::type
            function_type;

            typedef
                typename detail::result_of_<
                    function_type(BOOST_PROTO_DEFAULT_EVAL_TYPE(~, 1, Expr))
                >::type
            result_type;

            result_type operator ()(Expr &expr, Context &context) const
            {
                return this->invoke(
                    expr
                  , context
                  , is_member_function_pointer<function_type>()
                  , is_member_object_pointer<function_type>()
                );
            }

        private:
            result_type invoke(Expr &expr, Context &context, mpl::false_, mpl::false_) const
            {
                return BOOST_PROTO_DEFAULT_EVAL(~, 0, expr)(BOOST_PROTO_DEFAULT_EVAL(~, 1, expr));
            }

            result_type invoke(Expr &expr, Context &context, mpl::true_, mpl::false_) const
            {
                BOOST_PROTO_USE_GET_POINTER();
                typedef typename detail::class_member_traits<function_type>::class_type class_type;
                return (
                    BOOST_PROTO_GET_POINTER(class_type, (BOOST_PROTO_DEFAULT_EVAL(~, 1, expr))) ->*
                    BOOST_PROTO_DEFAULT_EVAL(~, 0, expr)
                )();
            }

            result_type invoke(Expr &expr, Context &context, mpl::false_, mpl::true_) const
            {
                BOOST_PROTO_USE_GET_POINTER();
                typedef typename detail::class_member_traits<function_type>::class_type class_type;
                return (
                    BOOST_PROTO_GET_POINTER(class_type, (BOOST_PROTO_DEFAULT_EVAL(~, 1, expr))) ->*
                    BOOST_PROTO_DEFAULT_EVAL(~, 0, expr)
                );
            }
        };

        // Additional specialization are generated by the preprocessor
        #include <boost/proto/context/detail/default_eval.hpp>

        #undef BOOST_PROTO_DEFAULT_EVAL_TYPE
        #undef BOOST_PROTO_DEFAULT_EVAL

        /// default_context
        ///
        struct default_context
        {
            /// default_context::eval
            ///
            template<typename Expr, typename ThisContext = default_context const>
            struct eval
              : default_eval<Expr, ThisContext>
            {};
        };

    } // namespace context

}} // namespace boost::proto

#undef UNREF

#endif


code:
#if !defined(BOOST_PROTO_DONT_USE_PREPROCESSED_FILES)

    #include <boost/proto/context/detail/preprocessed/callable_eval.hpp>

#elif !defined(BOOST_PP_IS_ITERATING)

    #define BOOST_PROTO_CHILD_N_TYPE(Z, N, Expr)                                                    \
        typedef typename proto::result_of::child_c<Expr const &, N>::type BOOST_PP_CAT(child, N);   \
        /**/

    #define BOOST_PROTO_CHILD_N(Z, N, expr)                                                         \
        proto::child_c<N>(expr)                                                                     \
        /**/

    #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
        #pragma wave option(preserve: 2, line: 0, output: "preprocessed/callable_eval.hpp")
    #endif

    ///////////////////////////////////////////////////////////////////////////////
    /// \file callable_eval.hpp
    /// Contains specializations of the callable_eval\<\> class template.
    //
    //  Copyright 2008 Eric Niebler. Distributed under the Boost
    //  Software License, Version 1.0. (See accompanying file
    //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

    #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
        #pragma wave option(preserve: 1)
    #endif

    #define BOOST_PP_ITERATION_PARAMS_1                                                             \
        (3, (1, BOOST_PROTO_MAX_ARITY, <boost/proto/context/detail/callable_eval.hpp>))
    #include BOOST_PP_ITERATE()

    #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
        #pragma wave option(output: null)
    #endif

    #undef BOOST_PROTO_CHILD_N_TYPE
    #undef BOOST_PROTO_CHILD_N

#else

    #define N BOOST_PP_ITERATION()

    namespace detail
    {
        template<typename Expr, typename Context>
        struct is_expr_handled<Expr, Context, N>
        {
            static callable_context_wrapper<Context> &sctx_;
            static Expr &sexpr_;
            static typename Expr::proto_tag &stag_;

            static const bool value =
                sizeof(yes_type) ==
                sizeof(
                    detail::check_is_expr_handled(
                        (sctx_(
                            stag_
                            BOOST_PP_ENUM_TRAILING(N, BOOST_PROTO_CHILD_N, sexpr_)
                        ), 0)
                    )
                );

            typedef mpl::bool_<value> type;
        };
    }

    namespace context
    {
        /// \brief A BinaryFunction that accepts a Proto expression and a
        /// callable context and calls the context with the expression tag
        /// and children as arguments, effectively fanning the expression
        /// out.
        ///
        /// <tt>callable_eval\<\></tt> requires that \c Context is a
        /// PolymorphicFunctionObject that can be invoked with \c Expr's
        /// tag and children as expressions, as follows:
        ///
        /// \code
        /// context(Expr::proto_tag(), child_c\<0\>(expr), child_c\<1\>(expr), ...)
        /// \endcode
        template<typename Expr, typename Context>
        struct callable_eval<Expr, Context, N>
        {
            BOOST_PP_REPEAT(N, BOOST_PROTO_CHILD_N_TYPE, Expr)

            typedef
                typename BOOST_PROTO_RESULT_OF<
                    Context(
                        typename Expr::proto_tag
                        BOOST_PP_ENUM_TRAILING_PARAMS(N, child)
                    )
                >::type
            result_type;

            /// \param expr The current expression
            /// \param context The callable evaluation context
            /// \return <tt>context(Expr::proto_tag(), child_c\<0\>(expr), child_c\<1\>(expr), ...)</tt>
            result_type operator ()(Expr &expr, Context &context) const
            {
                return context(
                    typename Expr::proto_tag()
                    BOOST_PP_ENUM_TRAILING(N, BOOST_PROTO_CHILD_N, expr)
                );
            }
        };
    }

    #undef N

#endif


code:
#if !defined(BOOST_PROTO_DONT_USE_PREPROCESSED_FILES)

    #include <boost/proto/context/detail/preprocessed/default_eval.hpp>

#elif !defined(BOOST_PP_IS_ITERATING)

    #define BOOST_PROTO_DEFAULT_EVAL_SHIFTED(Z, M, DATA)                                            \
        BOOST_PROTO_DEFAULT_EVAL(Z, BOOST_PP_ADD(M, 2), DATA)                                       \
        /**/

    #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
        #pragma wave option(preserve: 2, line: 0, output: "preprocessed/default_eval.hpp")
    #endif

    ///////////////////////////////////////////////////////////////////////////////
    /// \file default_eval.hpp
    /// Contains specializations of the default_eval\<\> class template.
    //
    //  Copyright 2008 Eric Niebler. Distributed under the Boost
    //  Software License, Version 1.0. (See accompanying file
    //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

    #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
        #pragma wave option(preserve: 1)
    #endif

    #define BOOST_PP_ITERATION_PARAMS_1                                                             \
        (3, (3, BOOST_PROTO_MAX_ARITY, <boost/proto/context/detail/default_eval.hpp>))
    #include BOOST_PP_ITERATE()

    #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
        #pragma wave option(output: null)
    #endif

    #undef BOOST_PROTO_DEFAULT_EVAL_SHIFTED

#else

    #define N BOOST_PP_ITERATION()

    template<typename Expr, typename Context>
    struct default_eval<Expr, Context, proto::tag::function, N>
    {
        typedef
            typename proto::detail::result_of_fixup<
                BOOST_PROTO_DEFAULT_EVAL_TYPE(~, 0, Expr)
            >::type
        function_type;

        typedef
            typename BOOST_PROTO_RESULT_OF<
                function_type(BOOST_PP_ENUM_SHIFTED(N, BOOST_PROTO_DEFAULT_EVAL_TYPE, Expr))
            >::type
        result_type;

        result_type operator ()(Expr &expr, Context &context) const
        {
            return this->invoke(expr, context, is_member_function_pointer<function_type>());
        }

    private:
        result_type invoke(Expr &expr, Context &context, mpl::false_) const
        {
            return BOOST_PROTO_DEFAULT_EVAL(~, 0, expr)(
                BOOST_PP_ENUM_SHIFTED(N, BOOST_PROTO_DEFAULT_EVAL, expr)
            );
        }

        result_type invoke(Expr &expr, Context &context, mpl::true_) const
        {
            BOOST_PROTO_USE_GET_POINTER();
            typedef typename detail::class_member_traits<function_type>::class_type class_type;
            return (
                BOOST_PROTO_GET_POINTER(class_type, (BOOST_PROTO_DEFAULT_EVAL(~, 1, expr))) ->*
                BOOST_PROTO_DEFAULT_EVAL(~, 0, expr)
            )(BOOST_PP_ENUM(BOOST_PP_SUB(N, 2), BOOST_PROTO_DEFAULT_EVAL_SHIFTED, expr));
        }
    };

    #undef N

#endif


code:
#if !defined(BOOST_PROTO_DONT_USE_PREPROCESSED_FILES)

    #include <boost/proto/context/detail/preprocessed/null_eval.hpp>

#elif !defined(BOOST_PP_IS_ITERATING)

    #define BOOST_PROTO_EVAL_N(Z, N, DATA)                                                          \
        proto::eval(proto::child_c<N>(expr), ctx);                                                  \
        /**/

    #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
        #pragma wave option(preserve: 2, line: 0, output: "preprocessed/null_eval.hpp")
    #endif

    ///////////////////////////////////////////////////////////////////////////////
    /// \file null_eval.hpp
    /// Contains specializations of the null_eval\<\> class template.
    //
    //  Copyright 2008 Eric Niebler. Distributed under the Boost
    //  Software License, Version 1.0. (See accompanying file
    //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

    #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
        #pragma wave option(preserve: 1)
    #endif

    #define BOOST_PP_ITERATION_PARAMS_1                                                             \
        (3, (1, BOOST_PROTO_MAX_ARITY, <boost/proto/context/detail/null_eval.hpp>))
    #include BOOST_PP_ITERATE()

    #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
        #pragma wave option(output: null)
    #endif

    #undef BOOST_PROTO_EVAL_N

#else

    #define N BOOST_PP_ITERATION()

    template<typename Expr, typename Context>
    struct null_eval<Expr, Context, N>
    {
        typedef void result_type;

        void operator ()(Expr &expr, Context &ctx) const
        {
            BOOST_PP_REPEAT(N, BOOST_PROTO_EVAL_N, ~)
        }
    };

    #undef N

#endif