code:
//  Boost string_algo library collection_traits.hpp header file  -------------//

//  Copyright Pavol Droba 2002-2003. 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)

// (C) Copyright Thorsten Ottosen 2002-2003. 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)

// (C) Copyright Jeremy Siek 2001. 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)

//  Original idea of container traits was proposed by Jeremy Siek and
//  Thorsten Ottosen. This implementation is lightweighted version
//  of container_traits adapter for usage with string_algo library

#ifndef BOOST_RANGE_STRING_COLLECTION_TRAITS_HPP
#define BOOST_RANGE_STRING_COLLECTION_TRAITS_HPP

#include <boost/type_traits/is_array.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <boost/mpl/eval_if.hpp>

// Implementation
#include <boost/range/detail/collection_traits_detail.hpp>

/*! \file
    Defines collection_traits class and related free-standing functions.
    This facility is used to unify the access to different types of collections.
    It allows the algorithms in the library to work with STL collections, c-style
    array, null-terminated c-strings (and more) using the same interface.
*/

namespace boost {
    namespace algorithm {

//  collection_traits template class -----------------------------------------//

        //! collection_traits class
        /*!
            Collection traits provide uniform access to different types of
            collections. This functionality allows to write generic algorithms
            which work with several different kinds of collections.

            Currently following collection types are supported:
                - containers with STL compatible container interface ( see ContainerConcept )
                    ( i.e. \c std::vector<>, \c std::list<>, \c std::string<> ... )
                - c-style array
                   ( \c char[10], \c int[15] ... )
                - null-terminated c-strings
                    ( \c char*, \c wchar_T* )
                - std::pair of iterators
                    ( i.e \c std::pair<vector<int>::iterator,vector<int>::iterator> )

            Collection traits provide an external collection interface operations.
            All are accessible using free-standing functions.

            The following operations are supported:
                - \c size()
                - \c empty()
                - \c begin()
                - \c end()

            Container traits have somewhat limited functionality on compilers not
            supporting partial template specialization and partial template ordering.
        */
        template< typename T >
        struct collection_traits
        {
        private:
            typedef typename ::boost::mpl::eval_if<
                    ::boost::algorithm::detail::is_pair<T>,
                        detail::pair_container_traits_selector<T>,
                        typename ::boost::mpl::eval_if<
                        ::boost::is_array<T>,
                            detail::array_container_traits_selector<T>,
                            typename ::boost::mpl::eval_if<
                            ::boost::is_pointer<T>,
                                detail::pointer_container_traits_selector<T>,
                                detail::default_container_traits_selector<T>
                            >
                        >
                >::type container_helper_type;
        public:
            //! Function type
            typedef container_helper_type function_type;
            //! Value type
            typedef typename
                container_helper_type::value_type value_type;
            //! Size type
            typedef typename
                container_helper_type::size_type size_type;
            //! Iterator type
            typedef typename
                container_helper_type::iterator iterator;
            //! Const iterator type
            typedef typename
                container_helper_type::const_iterator const_iterator;
            //! Result iterator type ( iterator of const_iterator, depending on the constness of the container )
            typedef typename
                container_helper_type::result_iterator result_iterator;
            //! Difference type
            typedef typename
                container_helper_type::difference_type difference_type;

        }; // 'collection_traits'

//  collection_traits metafunctions -----------------------------------------//

        //! Container value_type trait
        /*!
            Extract the type of elements contained in a container
        */
        template< typename C >
        struct value_type_of
        {
            typedef typename collection_traits<C>::value_type type;
        };

        //! Container difference trait
        /*!
            Extract the container's difference type
        */
        template< typename C >
        struct difference_type_of
        {
            typedef typename collection_traits<C>::difference_type type;
        };

        //! Container iterator trait
        /*!
            Extract the container's iterator type
        */
        template< typename C >
        struct iterator_of
        {
            typedef typename collection_traits<C>::iterator type;
        };

        //! Container const_iterator trait
        /*!
            Extract the container's const_iterator type
        */
        template< typename C >
        struct const_iterator_of
        {
            typedef typename collection_traits<C>::const_iterator type;
        };

        //! Container result_iterator
        /*!
            Extract the container's result_iterator type. This type maps to \c C::iterator
            for mutable container and \c C::const_iterator for const containers.
        */
        template< typename C >
        struct result_iterator_of
        {
            typedef typename collection_traits<C>::result_iterator type;
        };

//  collection_traits related functions -----------------------------------------//

        //! Free-standing size() function
        /*!
            Get the size of the container. Uses collection_traits.
        */
        template< typename C >
        inline typename collection_traits<C>::size_type
        size( const C& c )
        {
            return collection_traits<C>::function_type::size( c );
        }

        //! Free-standing empty() function
        /*!
            Check whether the container is empty. Uses container traits.
        */
        template< typename C >
        inline bool empty( const C& c )
        {
            return collection_traits<C>::function_type::empty( c );
        }

#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING

        //! Free-standing begin() function
        /*!
            Get the begin iterator of the container. Uses collection_traits.
        */
        template< typename C >
        inline typename collection_traits<C>::iterator
        begin( C& c )
        {
            return collection_traits<C>::function_type::begin( c );
        }

        //! Free-standing begin() function
        /*!
            \overload
        */
        template< typename C >
        inline typename collection_traits<C>::const_iterator
        begin( const C& c )
        {
            return collection_traits<C>::function_type::begin( c );
        }

        //! Free-standing end() function
        /*!
            Get the begin iterator of the container. Uses collection_traits.
        */
        template< typename C >
        inline typename collection_traits<C>::iterator
        end( C& c )
        {
            return collection_traits<C>::function_type::end( c );
        }

        //! Free-standing end() function
        /*!
            \overload
        */
        template< typename C >
        inline typename collection_traits<C>::const_iterator
        end( const C& c )
        {
            return collection_traits<C>::function_type::end( c );
        }

#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING

        //! Free-standing begin() function
        /*!
            \overload
        */
        template< typename C >
        inline typename collection_traits<C>::result_iterator
        begin( C& c )
        {
            return collection_traits<C>::function_type::begin( c );
        }

        //! Free-standing end() function
        /*!
            \overload
        */
        template< typename C >
        inline typename collection_traits<C>::result_iterator
        end( C& c )
        {
            return collection_traits<C>::function_type::end( c );
        }

#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING

    } // namespace algorithm
} // namespace boost

#endif // BOOST_STRING_COLLECTION_TRAITS_HPP


code:
//  Boost string_algo library collection_traits.hpp header file  -----------------------//

//  Copyright Pavol Droba 2002-2003. 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)

//  See http://www.boost.org for updates, documentation, and revision history.

#ifndef BOOST_RANGE_STRING_DETAIL_COLLECTION_TRAITS_HPP
#define BOOST_RANGE_STRING_DETAIL_COLLECTION_TRAITS_HPP

#include <cstddef>
#include <string>
#include <boost/type_traits/is_array.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/remove_pointer.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/detail/iterator.hpp>

// Container traits implementation ---------------------------------------------------------

namespace boost {
    namespace algorithm {
        namespace detail {

// Default collection traits -----------------------------------------------------------------

            // Default collection helper
            /*
                Wraps std::container compliant containers
            */
            template< typename ContainerT >
            struct default_container_traits
            {
                typedef typename ContainerT::value_type value_type;
                typedef typename ContainerT::iterator iterator;
                typedef typename ContainerT::const_iterator const_iterator;
                typedef typename
                    ::boost::mpl::if_< ::boost::is_const<ContainerT>,
                        const_iterator,
                        iterator
                    >::type result_iterator;
                typedef typename ContainerT::difference_type difference_type;
                typedef typename ContainerT::size_type size_type;

                // static operations
                template< typename C >
                static size_type size( const C& c )
                {
                    return c.size();
                }

                template< typename C >
                static bool empty( const C& c )
                {
                    return c.empty();
                }

#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING

                template< typename C >
                static iterator begin( C& c )
                {
                    return c.begin();
                }

                template< typename C >
                static const_iterator begin( const C& c )
                {
                    return c.begin();
                }

                template< typename C >
                static iterator end( C& c )
                {
                    return c.end();
                }

                template< typename C >
                static const_iterator end( const C& c )
                {
                    return c.end();
                }

#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING

                template< typename C >
                static result_iterator begin( C& c )
                {
                    return c.begin();
                }

                template< typename C >
                static result_iterator end( C& c )
                {
                    return c.end();
                }

#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING

            };

            template<typename T>
            struct default_container_traits_selector
            {
                typedef default_container_traits<T> type;
            };

// Pair container traits ---------------------------------------------------------------------

            typedef double yes_type;
            typedef char no_type;

            // pair selector
            template< typename T, typename U >
            yes_type is_pair_impl( const std::pair<T,U>* );
            no_type is_pair_impl( ... );

            template<typename T> struct is_pair
            {
            private:
                static T* t;
            public:
                BOOST_STATIC_CONSTANT( bool, value=
                    sizeof(is_pair_impl(t))==sizeof(yes_type) );
            };

            // pair helper
            template< typename PairT >
            struct pair_container_traits
            {
                typedef typename PairT::first_type element_type;

                typedef typename ::boost::detail::
                    iterator_traits<element_type>::value_type value_type;
                typedef std::size_t size_type;
                typedef typename ::boost::detail::
                    iterator_traits<element_type>::difference_type difference_type;

                typedef element_type iterator;
                typedef element_type const_iterator;
                typedef element_type result_iterator;

                // static operations
                template< typename P >
                static size_type size( const P& p )
                {
                    difference_type diff = std::distance( p.first, p.second );
                    if ( diff < 0 )
                        return 0;
                    else
                        return diff;
                }

                template< typename P >
                static bool empty( const P& p )
                {
                    return p.first==p.second;
                }

                template< typename P >
                static const_iterator begin( const P& p )
                {
                    return p.first;
                }

                template< typename P >
                static const_iterator end( const P& p )
                {
                    return p.second;
                }
            }; // 'pair_container_helper'

            template<typename T>
            struct pair_container_traits_selector
            {
                typedef pair_container_traits<T> type;
            };

// Array container traits ---------------------------------------------------------------

            // array traits ( partial specialization )
            template< typename T >
            struct array_traits;

            template< typename T, std::size_t sz >
            struct array_traits<T[sz]>
            {
                // typedef
                typedef T* iterator;
                typedef const T* const_iterator;
                typedef T value_type;
                typedef std::size_t size_type;
                typedef std::ptrdiff_t difference_type;

                // size of the array ( static );
                BOOST_STATIC_CONSTANT( size_type, array_size = sz );
            };

            // array length resolving
            /*
                Lenght of string contained in a static array could
                be different from the size of the array.
                For string processing we need the length without
                terminating 0.

                Therefore, the length is calculated for char and wchar_t
                using char_traits, rather then simply returning
                the array size.
            */
            template< typename T >
            struct array_length_selector
            {
                template< typename TraitsT >
                struct array_length
                {
                    typedef typename
                        TraitsT::size_type size_type;

                    BOOST_STATIC_CONSTANT(
                        size_type,
                        array_size=TraitsT::array_size );

                    template< typename A >
                    static size_type length( const A& )
                    {
                        return array_size;
                    }

                    template< typename A >
                    static bool empty( const A& )
                    {
                        return array_size==0;
                    }
                };
            };

            // specialization for char
            template<>
            struct array_length_selector<char>
            {
                template< typename TraitsT >
                struct array_length
                {
                    typedef typename
                        TraitsT::size_type size_type;

                    template< typename A >
                    static size_type length( const A& a )
                    {
                        if ( a==0 )
                            return 0;
                        else
                            return std::char_traits<char>::length(a);
                    }

                    template< typename A >
                    static bool empty( const A& a )
                    {
                        return a==0 || a[0]==0;
                    }
                };
            };

            // specialization for wchar_t
            template<>
            struct array_length_selector<wchar_t>
            {
                template< typename TraitsT >
                struct array_length
                {
                    typedef typename
                        TraitsT::size_type size_type;

                    template< typename A >
                    static size_type length( const A& a )
                    {
                        if ( a==0 )
                            return 0;
                        else
                            return std::char_traits<wchar_t>::length(a);
                    }

                    template< typename A >
                    static bool empty( const A& a )
                    {
                        return a==0 || a[0]==0;
                    }
                };
            };

            template< typename T >
            struct array_container_traits
            {
            private:
                // resolve array traits
                typedef array_traits<T> traits_type;

            public:
                typedef typename
                    traits_type::value_type value_type;
                typedef typename
                    traits_type::iterator iterator;
                typedef typename
                    traits_type::const_iterator const_iterator;
                typedef typename
                    traits_type::size_type size_type;
                typedef typename
                    traits_type::difference_type difference_type;

                typedef typename
                    ::boost::mpl::if_< ::boost::is_const<T>,
                        const_iterator,
                        iterator
                    >::type result_iterator;

            private:
                // resolve array size
                typedef typename
                    ::boost::remove_cv<value_type>::type char_type;
                typedef typename
                    array_length_selector<char_type>::
                        BOOST_NESTED_TEMPLATE array_length<traits_type> array_length_type;

            public:
                BOOST_STATIC_CONSTANT( size_type, array_size = traits_type::array_size );

                // static operations
                template< typename A >
                static size_type size( const A& a )
                {
                    return array_length_type::length(a);
                }

                template< typename A >
                static bool empty( const A& a )
                {
                    return array_length_type::empty(a);
                }

#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING

                template< typename A >
                static iterator begin( A& a )
                {
                    return a;
                }

                template< typename A >
                static const_iterator begin( const A& a )
                {
                    return a;
                }

                template< typename A >
                static iterator end( A& a )
                {
                    return a+array_length_type::length(a);
                }

                template< typename A >
                static const_iterator end( const A& a )
                {
                    return a+array_length_type::length(a);
                }

#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING

                template< typename A >
                static result_iterator begin( A& a )
                {
                    return a;
                }

                template< typename A >
                static result_iterator end( A& a )
                {
                    return a+array_length_type::length(a);
                }

#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING

            };

            template<typename T>
            struct array_container_traits_selector
            {
                typedef array_container_traits<T> type;
            };

// Pointer container traits ---------------------------------------------------------------

            template<typename T>
            struct pointer_container_traits
            {
                typedef typename
                    ::boost::remove_pointer<T>::type value_type;

                typedef typename
                    ::boost::remove_cv<value_type>::type char_type;
                typedef ::std::char_traits<char_type> char_traits;

                typedef value_type* iterator;
                typedef const value_type* const_iterator;
                typedef std::ptrdiff_t difference_type;
                typedef std::size_t size_type;

                typedef typename
                    ::boost::mpl::if_< ::boost::is_const<T>,
                        const_iterator,
                        iterator
                    >::type result_iterator;

                // static operations
                template< typename P >
                static size_type size( const P& p )
                {
                    if ( p==0 )
                        return 0;
                    else
                        return char_traits::length(p);
                }

                template< typename P >
                static bool empty( const P& p )
                {
                    return p==0 || p[0]==0;
                }

#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING

                template< typename P >
                static iterator begin( P& p )
                {
                    return p;
                }

                template< typename P >
                static const_iterator begin( const P& p )
                {
                    return p;
                }

                template< typename P >
                static iterator end( P& p )
                {
                    if ( p==0 )
                        return p;
                    else
                        return p+char_traits::length(p);
                }

                template< typename P >
                static const_iterator end( const P& p )
                {
                    if ( p==0 )
                        return p;
                    else
                        return p+char_traits::length(p);
                }

#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING

                template< typename P >
                static result_iterator begin( P& p )
                {
                    return p;
                }

                template< typename P >
                static result_iterator end( P& p )
                {
                    if ( p==0 )
                        return p;
                    else
                        return p+char_traits::length(p);
                }

#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
            };

            template<typename T>
            struct pointer_container_traits_selector
            {
                typedef pointer_container_traits<T> type;
            };

        } // namespace detail
    } // namespace algorithm
} // namespace boost

#endif  // BOOST_STRING_DETAIL_COLLECTION_HPP

license: mit


code:
// Boost.Range library
//
//  Copyright Neil Groves 2014. 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)
//
// For more information, see http://www.boost.org/libs/range/
//
#ifndef BOOST_RANGE_DETAIL_COMBINE_CXX03_HPP
#define BOOST_RANGE_DETAIL_COMBINE_CXX03_HPP

#ifndef BOOST_RANGE_MIN_COMBINE_ARGS
#define BOOST_RANGE_MIN_COMBINE_ARGS 2
#endif

#ifndef BOOST_RANGE_MAX_COMBINE_ARGS
#define BOOST_RANGE_MAX_COMBINE_ARGS 5
#endif

#include <boost/config.hpp>
#include <boost/iterator/zip_iterator.hpp>
#include <boost/preprocessor/arithmetic/dec.hpp>
#include <boost/preprocessor/arithmetic/div.hpp>
#include <boost/preprocessor/arithmetic/mul.hpp>
#include <boost/preprocessor/control.hpp>
#include <boost/preprocessor/control/while.hpp>
#include <boost/preprocessor/facilities/empty.hpp>
#include <boost/preprocessor/facilities/identity.hpp>
#include <boost/preprocessor/iteration/local.hpp>
#include <boost/preprocessor/punctuation/comma.hpp>
#include <boost/preprocessor/repetition.hpp>
#include <boost/preprocessor/tuple/elem.hpp>
#include <boost/range/iterator_range_core.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/utility/result_of.hpp>

#include <vector>
#include <list>

namespace boost
{
    namespace range_detail
    {

template<typename F, typename T, int SIZE>
struct combined_result_impl;

template<typename F, typename T>
struct combined_result
    : combined_result_impl<F, T, tuples::length<T>::value>
{
};

#define BOOST_RANGE_combined_element(z, n, data) \
    typename tuples::element<n, T>::type

#define BOOST_RANGE_combined_result(z, n, data) \
    template<typename F, typename T> \
    struct combined_result_impl <F,T,n> \
        : result_of<F(BOOST_PP_ENUM(n, BOOST_RANGE_combined_element, ~))> \
    { \
    };

#define BOOST_PP_LOCAL_MACRO(n) BOOST_RANGE_combined_result(~,n,~)

#define BOOST_PP_LOCAL_LIMITS (BOOST_RANGE_MIN_COMBINE_ARGS, \
                               BOOST_RANGE_MAX_COMBINE_ARGS)
#include BOOST_PP_LOCAL_ITERATE()

#define BOOST_RANGE_combined_get(z, n, data) get<n>(tuple)

#define BOOST_RANGE_combined_unpack(z, n, data) \
    template<typename F, typename T> inline \
    typename combined_result<F,T>::type \
    unpack_(mpl::int_<n>, F f, const T& tuple) \
    { \
        return f(BOOST_PP_ENUM(n, BOOST_RANGE_combined_get, ~)); \
    }

#define BOOST_PP_LOCAL_MACRO(n) BOOST_RANGE_combined_unpack(~,n,~)
#define BOOST_PP_LOCAL_LIMITS (BOOST_RANGE_MIN_COMBINE_ARGS, \
                               BOOST_RANGE_MAX_COMBINE_ARGS)
#include BOOST_PP_LOCAL_ITERATE()

} // namespace range_detail

namespace range
{

#define BOOST_RANGE_combined_seq(z, n, data) boost::data(BOOST_PP_CAT(r,n))

#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES

#include <boost/range/detail/combine_no_rvalue.hpp>

#else // by using rvalue references we avoid requiring 2^n overloads.

#include <boost/range/detail/combine_rvalue.hpp>

#endif

#define BOOST_PP_LOCAL_MACRO(n) BOOST_RANGE_combine(~,n,~)
#define BOOST_PP_LOCAL_LIMITS (BOOST_RANGE_MIN_COMBINE_ARGS, \
                               BOOST_RANGE_MAX_COMBINE_ARGS)
#include BOOST_PP_LOCAL_ITERATE()

    } // namespace range

    using boost::range::combine;

} // namespace boost

#endif // include guard

#undef BOOST_RANGE_combined_element
#undef BOOST_RANGE_combined_result
#undef BOOST_RANGE_combined_get
#undef BOOST_RANGE_combined_unpack
#undef BOOST_RANGE_combined_seq
#undef BOOST_RANGE_combined_exp_pred
#undef BOOST_RANGE_combined_exp_op
#undef BOOST_RANGE_combined_exp
#undef BOOST_RANGE_combined_bitset_pred
#undef BOOST_RANGE_combined_bitset_op
#undef BOOST_RANGE_combined_bitset
#undef BOOST_RANGE_combined_range_iterator
#undef BOOST_RANGE_combined_args
#undef BOOST_RANGE_combine_impl
#undef BOOST_RANGE_combine


code:
//  Copyright Neil Groves 2014. 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)
//
//
// For more information, see http://www.boost.org/libs/range/
//
#ifndef BOOST_RANGE_DETAIL_COMBINE_CXX11_HPP
#define BOOST_RANGE_DETAIL_COMBINE_CXX11_HPP

#include <boost/range/iterator_range_core.hpp>
#include <boost/range/iterator.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/iterator/zip_iterator.hpp>

#include <fstream>

namespace boost
{
    namespace range
    {

template<typename... Ranges>
auto combine(Ranges&&... rngs) ->
    combined_range<decltype(boost::make_tuple(boost::begin(rngs)...))>
{
    return combined_range<decltype(boost::make_tuple(boost::begin(rngs)...))>(
                boost::make_tuple(boost::begin(rngs)...),
                boost::make_tuple(boost::end(rngs)...));
}

    } // namespace range

using range::combine;

} // namespace boost

#endif // include guard


code:
// Boost.Range library
//
//  Copyright Neil Groves 2014. 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)
//
// For more information, see http://www.boost.org/libs/range/
//
#define BOOST_RANGE_combined_exp_pred(d, data) BOOST_PP_TUPLE_ELEM(3, 0, data)

#define BOOST_RANGE_combined_exp_op(d, data) \
 ( \
    BOOST_PP_DEC( \
       BOOST_PP_TUPLE_ELEM(3, 0, data) \
    ), \
    BOOST_PP_TUPLE_ELEM(3, 1, data), \
    BOOST_PP_MUL_D( \
       d, \
       BOOST_PP_TUPLE_ELEM(3, 2, data), \
       BOOST_PP_TUPLE_ELEM(3, 1, data) \
    ) \
 )

#define BOOST_RANGE_combined_exp(x, n) \
  BOOST_PP_TUPLE_ELEM(3, 2, \
  BOOST_PP_WHILE(BOOST_RANGE_combined_exp_pred, \
                 BOOST_RANGE_combined_exp_op, (n, x, 1)))

#define BOOST_RANGE_combined_bitset_pred(n, state) \
    BOOST_PP_TUPLE_ELEM(2,1,state)

#define BOOST_RANGE_combined_bitset_op(d, state) \
    (BOOST_PP_DIV_D(d, BOOST_PP_TUPLE_ELEM(2,0,state), 2), \
     BOOST_PP_DEC(BOOST_PP_TUPLE_ELEM(2,1,state)))

#define BOOST_RANGE_combined_bitset(i, n) \
BOOST_PP_MOD(BOOST_PP_TUPLE_ELEM(2, 0, \
      BOOST_PP_WHILE(BOOST_RANGE_combined_bitset_pred, \
                     BOOST_RANGE_combined_bitset_op, (i,n))), 2)

#define BOOST_RANGE_combined_range_iterator(z, n, i) \
  typename range_iterator< \
      BOOST_PP_CAT(R,n)          \
      BOOST_PP_IF( \
          BOOST_RANGE_combined_bitset(i,n), \
          BOOST_PP_IDENTITY(const), \
          BOOST_PP_EMPTY)() \
  >::type

#define BOOST_RANGE_combined_args(z, n, i) \
  BOOST_PP_CAT(R, n) \
  BOOST_PP_IF(BOOST_RANGE_combined_bitset(i,n), const&, &)  \
  BOOST_PP_CAT(r, n)

#define BOOST_RANGE_combine_impl(z, i, n)\
    template<BOOST_PP_ENUM_PARAMS(n, typename R)> \
    inline range::combined_range< \
        boost::tuple<BOOST_PP_ENUM(n, BOOST_RANGE_combined_range_iterator, i)> \
    > \
    combine(BOOST_PP_ENUM(n, BOOST_RANGE_combined_args, i)) \
    { \
        typedef tuple< \
            BOOST_PP_ENUM(n, BOOST_RANGE_combined_range_iterator, i) \
        > rng_tuple_t;   \
        return range::combined_range<rng_tuple_t>( \
            rng_tuple_t(BOOST_PP_ENUM(n, BOOST_RANGE_combined_seq, begin)), \
            rng_tuple_t(BOOST_PP_ENUM(n, BOOST_RANGE_combined_seq, end))); \
    }

#define BOOST_RANGE_combine(z, n, data) \
  BOOST_PP_REPEAT(BOOST_RANGE_combined_exp(2,n), BOOST_RANGE_combine_impl, n)


code:
// Boost.Range library
//
//  Copyright Neil Groves 2014. 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)
//
// For more information, see http://www.boost.org/libs/range/
//
#define BOOST_RANGE_combined_args(z, n, i) \
    BOOST_PP_CAT(R, n)&& BOOST_PP_CAT(r, n)

#define BOOST_RANGE_combined_range_iterator(z, n, i) \
    typename range_iterator< \
        typename remove_reference<BOOST_PP_CAT(R,n)>::type \
  >::type

#define BOOST_RANGE_combine(z, n, data) \
    template <BOOST_PP_ENUM_PARAMS(n, typename R)> \
    inline range::combined_range< \
        tuple<BOOST_PP_ENUM(n, BOOST_RANGE_combined_range_iterator, ~)> \
    > \
    combine(BOOST_PP_ENUM(n, BOOST_RANGE_combined_args, ~)) \
    { \
        typedef tuple< \
            BOOST_PP_ENUM(n, BOOST_RANGE_combined_range_iterator, ~) \
        > rng_tuple_t; \
        return range::combined_range<rng_tuple_t>( \
            rng_tuple_t(BOOST_PP_ENUM(n, BOOST_RANGE_combined_seq, begin)), \
            rng_tuple_t(BOOST_PP_ENUM(n, BOOST_RANGE_combined_seq, end))); \
    }


code:
// Boost.Range library
//
//  Copyright Thorsten Ottosen 2003-2004. 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)
//
// For more information, see http://www.boost.org/libs/range/
//

#ifndef BOOST_RANGE_DETAIL_COMMON_HPP
#define BOOST_RANGE_DETAIL_COMMON_HPP

#if defined(_MSC_VER)
# pragma once
#endif

#include <boost/range/config.hpp>
#include <boost/range/detail/sfinae.hpp>
#include <boost/type_traits/is_void.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/or.hpp>
#include <cstddef>

//////////////////////////////////////////////////////////////////////////////
// missing partial specialization  workaround.
//////////////////////////////////////////////////////////////////////////////

namespace boost
{
    namespace range_detail
    {
        // 1 = std containers
        // 2 = std::pair
        // 3 = const std::pair
        // 4 = array
        // 5 = const array
        // 6 = char array
        // 7 = wchar_t array
        // 8 = char*
        // 9 = const char*
        // 10 = whar_t*
        // 11 = const wchar_t*
        // 12 = string

        typedef mpl::int_<1>::type    std_container_;
        typedef mpl::int_<2>::type    std_pair_;
        typedef mpl::int_<3>::type    const_std_pair_;
        typedef mpl::int_<4>::type    array_;
        typedef mpl::int_<5>::type    const_array_;
        typedef mpl::int_<6>::type    char_array_;
        typedef mpl::int_<7>::type    wchar_t_array_;
        typedef mpl::int_<8>::type    char_ptr_;
        typedef mpl::int_<9>::type    const_char_ptr_;
        typedef mpl::int_<10>::type   wchar_t_ptr_;
        typedef mpl::int_<11>::type   const_wchar_t_ptr_;
        typedef mpl::int_<12>::type   string_;

        template< typename C >
        struct range_helper
        {
            static C* c;
            static C  ptr;

            BOOST_STATIC_CONSTANT( bool, is_pair_                = sizeof( boost::range_detail::is_pair_impl( c ) ) == sizeof( yes_type ) );
            BOOST_STATIC_CONSTANT( bool, is_char_ptr_            = sizeof( boost::range_detail::is_char_ptr_impl( ptr ) ) == sizeof( yes_type ) );
            BOOST_STATIC_CONSTANT( bool, is_const_char_ptr_      = sizeof( boost::range_detail::is_const_char_ptr_impl( ptr ) ) == sizeof( yes_type ) );
            BOOST_STATIC_CONSTANT( bool, is_wchar_t_ptr_         = sizeof( boost::range_detail::is_wchar_t_ptr_impl( ptr ) ) == sizeof( yes_type ) );
            BOOST_STATIC_CONSTANT( bool, is_const_wchar_t_ptr_   = sizeof( boost::range_detail::is_const_wchar_t_ptr_impl( ptr ) ) == sizeof( yes_type ) );
            BOOST_STATIC_CONSTANT( bool, is_char_array_          = sizeof( boost::range_detail::is_char_array_impl( ptr ) ) == sizeof( yes_type ) );
            BOOST_STATIC_CONSTANT( bool, is_wchar_t_array_       = sizeof( boost::range_detail::is_wchar_t_array_impl( ptr ) ) == sizeof( yes_type ) );
            BOOST_STATIC_CONSTANT( bool, is_string_              = (boost::mpl::or_<boost::mpl::bool_<is_const_char_ptr_>, boost::mpl::bool_<is_const_wchar_t_ptr_> >::value ));
            BOOST_STATIC_CONSTANT( bool, is_array_               = boost::is_array<C>::value );

        };

        template< typename C >
        class range
        {
            typedef BOOST_RANGE_DEDUCED_TYPENAME   boost::mpl::if_c< ::boost::range_detail::range_helper<C>::is_pair_,
                                                                  boost::range_detail::std_pair_,
                                                                  void >::type pair_t;
            typedef BOOST_RANGE_DEDUCED_TYPENAME   boost::mpl::if_c< ::boost::range_detail::range_helper<C>::is_array_,
                                                                    boost::range_detail::array_,
                                                                    pair_t >::type array_t;
            typedef BOOST_RANGE_DEDUCED_TYPENAME   boost::mpl::if_c< ::boost::range_detail::range_helper<C>::is_string_,
                                                                    boost::range_detail::string_,
                                                                    array_t >::type string_t;
            typedef BOOST_RANGE_DEDUCED_TYPENAME   boost::mpl::if_c< ::boost::range_detail::range_helper<C>::is_const_char_ptr_,
                                                                    boost::range_detail::const_char_ptr_,
                                                                    string_t >::type const_char_ptr_t;
            typedef BOOST_RANGE_DEDUCED_TYPENAME   boost::mpl::if_c< ::boost::range_detail::range_helper<C>::is_char_ptr_,
                                                                    boost::range_detail::char_ptr_,
                                                                    const_char_ptr_t >::type char_ptr_t;
            typedef BOOST_RANGE_DEDUCED_TYPENAME   boost::mpl::if_c< ::boost::range_detail::range_helper<C>::is_const_wchar_t_ptr_,
                                                                    boost::range_detail::const_wchar_t_ptr_,
                                                                    char_ptr_t >::type const_wchar_ptr_t;
            typedef BOOST_RANGE_DEDUCED_TYPENAME   boost::mpl::if_c< ::boost::range_detail::range_helper<C>::is_wchar_t_ptr_,
                                                                    boost::range_detail::wchar_t_ptr_,
                                                                    const_wchar_ptr_t >::type wchar_ptr_t;
            typedef BOOST_RANGE_DEDUCED_TYPENAME   boost::mpl::if_c< ::boost::range_detail::range_helper<C>::is_wchar_t_array_,
                                                                    boost::range_detail::wchar_t_array_,
                                                                    wchar_ptr_t >::type wchar_array_t;
            typedef BOOST_RANGE_DEDUCED_TYPENAME   boost::mpl::if_c< ::boost::range_detail::range_helper<C>::is_char_array_,
                                                                    boost::range_detail::char_array_,
                                                                    wchar_array_t >::type char_array_t;
        public:
            typedef BOOST_RANGE_DEDUCED_TYPENAME   boost::mpl::if_c< ::boost::is_void<char_array_t>::value,
                                                                    boost::range_detail::std_container_,
                                                                    char_array_t >::type type;
        }; // class 'range'
    }
}

#endif


code:
// Boost.Range library
//
//  Copyright Neil Groves 2014. 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)
//
// For more information, see http://www.boost.org/libs/range/
//
#ifndef BOOST_RANGE_DETAIL_DEFAULT_CONSTRUCTIBLE_UNARY_FN_HPP_INCLUDED
#define BOOST_RANGE_DETAIL_DEFAULT_CONSTRUCTIBLE_UNARY_FN_HPP_INCLUDED

#include <boost/optional/optional.hpp>
#include <boost/mpl/if.hpp>
#include <boost/type_traits/has_trivial_constructor.hpp>

namespace boost
{
    namespace range_detail
    {

template<typename F, typename R>
class default_constructible_unary_fn_wrapper
{
public:
    typedef R result_type;

    default_constructible_unary_fn_wrapper()
    {
    }
    default_constructible_unary_fn_wrapper(const F& source)
        : m_impl(source)
    {
    }
    template<typename Arg>
    R operator()(const Arg& arg) const
    {
        BOOST_ASSERT(m_impl);
        return (*m_impl)(arg);
    }
    template<typename Arg>
    R operator()(Arg& arg) const
    {
        BOOST_ASSERT(m_impl);
        return (*m_impl)(arg);
    }
private:
    boost::optional<F> m_impl;
};

template<typename F, typename R>
struct default_constructible_unary_fn_gen
{
    typedef typename boost::mpl::if_<
        boost::has_trivial_default_constructor<F>,
        F,
        default_constructible_unary_fn_wrapper<F,R>
    >::type type;
};

    } // namespace range_detail
} // namespace boost

#endif // include guard


code:
// Boost.Range library
//
//  Copyright Neil Groves 2009. 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)
//
// Acknowledgements:
// aschoedl supplied a fix to supply the level of interoperability I had
// originally intended, but failed to implement.
//
// For more information, see http://www.boost.org/libs/range/
//
#ifndef BOOST_RANGE_DETAIL_DEMOTE_ITERATOR_TRAVERSAL_TAG_HPP_INCLUDED
#define BOOST_RANGE_DETAIL_DEMOTE_ITERATOR_TRAVERSAL_TAG_HPP_INCLUDED

#include <boost/iterator/iterator_categories.hpp>

namespace boost
{
    namespace range_detail
    {

template<class IteratorTraversalTag1, class IteratorTraversalTag2>
struct inner_demote_iterator_traversal_tag
{
};

#define BOOST_DEMOTE_TRAVERSAL_TAG( Tag1, Tag2, ResultTag ) \
template<> struct inner_demote_iterator_traversal_tag< Tag1 , Tag2 > \
{ \
    typedef ResultTag type; \
};

BOOST_DEMOTE_TRAVERSAL_TAG( no_traversal_tag, no_traversal_tag,            no_traversal_tag )
BOOST_DEMOTE_TRAVERSAL_TAG( no_traversal_tag, incrementable_traversal_tag, no_traversal_tag )
BOOST_DEMOTE_TRAVERSAL_TAG( no_traversal_tag, single_pass_traversal_tag,   no_traversal_tag )
BOOST_DEMOTE_TRAVERSAL_TAG( no_traversal_tag, forward_traversal_tag,       no_traversal_tag )
BOOST_DEMOTE_TRAVERSAL_TAG( no_traversal_tag, bidirectional_traversal_tag, no_traversal_tag )
BOOST_DEMOTE_TRAVERSAL_TAG( no_traversal_tag, random_access_traversal_tag, no_traversal_tag )

BOOST_DEMOTE_TRAVERSAL_TAG( incrementable_traversal_tag, no_traversal_tag,            no_traversal_tag            )
BOOST_DEMOTE_TRAVERSAL_TAG( incrementable_traversal_tag, incrementable_traversal_tag, incrementable_traversal_tag )
BOOST_DEMOTE_TRAVERSAL_TAG( incrementable_traversal_tag, single_pass_traversal_tag,   incrementable_traversal_tag )
BOOST_DEMOTE_TRAVERSAL_TAG( incrementable_traversal_tag, forward_traversal_tag,       incrementable_traversal_tag )
BOOST_DEMOTE_TRAVERSAL_TAG( incrementable_traversal_tag, bidirectional_traversal_tag, incrementable_traversal_tag )
BOOST_DEMOTE_TRAVERSAL_TAG( incrementable_traversal_tag, random_access_traversal_tag, incrementable_traversal_tag )

BOOST_DEMOTE_TRAVERSAL_TAG( single_pass_traversal_tag, no_traversal_tag,            no_traversal_tag            )
BOOST_DEMOTE_TRAVERSAL_TAG( single_pass_traversal_tag, incrementable_traversal_tag, incrementable_traversal_tag )
BOOST_DEMOTE_TRAVERSAL_TAG( single_pass_traversal_tag, single_pass_traversal_tag,   single_pass_traversal_tag   )
BOOST_DEMOTE_TRAVERSAL_TAG( single_pass_traversal_tag, forward_traversal_tag,       single_pass_traversal_tag   )
BOOST_DEMOTE_TRAVERSAL_TAG( single_pass_traversal_tag, bidirectional_traversal_tag, single_pass_traversal_tag   )
BOOST_DEMOTE_TRAVERSAL_TAG( single_pass_traversal_tag, random_access_traversal_tag, single_pass_traversal_tag   )

BOOST_DEMOTE_TRAVERSAL_TAG( forward_traversal_tag, no_traversal_tag,            no_traversal_tag            )
BOOST_DEMOTE_TRAVERSAL_TAG( forward_traversal_tag, incrementable_traversal_tag, incrementable_traversal_tag )
BOOST_DEMOTE_TRAVERSAL_TAG( forward_traversal_tag, single_pass_traversal_tag,   single_pass_traversal_tag   )
BOOST_DEMOTE_TRAVERSAL_TAG( forward_traversal_tag, forward_traversal_tag,       forward_traversal_tag       )
BOOST_DEMOTE_TRAVERSAL_TAG( forward_traversal_tag, bidirectional_traversal_tag, forward_traversal_tag       )
BOOST_DEMOTE_TRAVERSAL_TAG( forward_traversal_tag, random_access_traversal_tag, forward_traversal_tag       )

BOOST_DEMOTE_TRAVERSAL_TAG( bidirectional_traversal_tag, no_traversal_tag,            no_traversal_tag            )
BOOST_DEMOTE_TRAVERSAL_TAG( bidirectional_traversal_tag, incrementable_traversal_tag, incrementable_traversal_tag )
BOOST_DEMOTE_TRAVERSAL_TAG( bidirectional_traversal_tag, single_pass_traversal_tag,   single_pass_traversal_tag   )
BOOST_DEMOTE_TRAVERSAL_TAG( bidirectional_traversal_tag, forward_traversal_tag,       forward_traversal_tag       )
BOOST_DEMOTE_TRAVERSAL_TAG( bidirectional_traversal_tag, bidirectional_traversal_tag, bidirectional_traversal_tag )
BOOST_DEMOTE_TRAVERSAL_TAG( bidirectional_traversal_tag, random_access_traversal_tag, bidirectional_traversal_tag )

BOOST_DEMOTE_TRAVERSAL_TAG( random_access_traversal_tag, no_traversal_tag,            no_traversal_tag            )
BOOST_DEMOTE_TRAVERSAL_TAG( random_access_traversal_tag, incrementable_traversal_tag, incrementable_traversal_tag )
BOOST_DEMOTE_TRAVERSAL_TAG( random_access_traversal_tag, single_pass_traversal_tag,   single_pass_traversal_tag   )
BOOST_DEMOTE_TRAVERSAL_TAG( random_access_traversal_tag, forward_traversal_tag,       forward_traversal_tag       )
BOOST_DEMOTE_TRAVERSAL_TAG( random_access_traversal_tag, bidirectional_traversal_tag, bidirectional_traversal_tag )
BOOST_DEMOTE_TRAVERSAL_TAG( random_access_traversal_tag, random_access_traversal_tag, random_access_traversal_tag )

#undef BOOST_DEMOTE_TRAVERSAL_TAG

template<class IteratorTraversalTag1, class IteratorTraversalTag2>
struct demote_iterator_traversal_tag
    : inner_demote_iterator_traversal_tag<
        typename boost::iterators::pure_traversal_tag< IteratorTraversalTag1 >::type,
        typename boost::iterators::pure_traversal_tag< IteratorTraversalTag2 >::type
      >
{
};

    } // namespace range_detail
} // namespace boost

#endif // include guard


code:
// Boost.Range library
//
//  Copyright Thorsten Ottosen 2003-2004. 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)
//
// For more information, see http://www.boost.org/libs/range/
//

#ifndef BOOST_RANGE_DETAIL_DETAIL_STR_HPP
#define BOOST_RANGE_DETAIL_DETAIL_STR_HPP

#include <boost/config.hpp> // BOOST_MSVC
#include <boost/range/iterator.hpp>

namespace boost
{

    namespace range_detail
    {
        //
        // iterator
        //

        template<>
        struct range_iterator_<char_array_>
        {
            template< typename T >
            struct pts
            {
                 typedef BOOST_RANGE_DEDUCED_TYPENAME
                    remove_extent<T>::type* type;
            };
        };

        template<>
        struct range_iterator_<char_ptr_>
        {
            template< typename S >
            struct pts
            {
                typedef char* type;
            };
        };

        template<>
        struct range_iterator_<const_char_ptr_>
        {
            template< typename S >
            struct pts
            {
                typedef const char* type;
            };
        };

        template<>
        struct range_iterator_<wchar_t_ptr_>
        {
            template< typename S >
            struct pts
            {
                typedef wchar_t* type;
            };
        };

        template<>
        struct range_iterator_<const_wchar_t_ptr_>
        {
             template< typename S >
             struct pts
             {
                 typedef const wchar_t* type;
             };
        };

        //
        // const iterator
        //

        template<>
        struct range_const_iterator_<char_array_>
        {
            template< typename T >
            struct pts
            {
                typedef const BOOST_RANGE_DEDUCED_TYPENAME
                    remove_extent<T>::type* type;
            };
        };

        template<>
        struct range_const_iterator_<char_ptr_>
        {
            template< typename S >
            struct pts
            {
                typedef const char* type;
            };
        };

        template<>
        struct range_const_iterator_<const_char_ptr_>
        {
            template< typename S >
            struct pts
            {
                typedef const char* type;
            };
        };

        template<>
        struct range_const_iterator_<wchar_t_ptr_>
        {
            template< typename S >
            struct pts
            {
                typedef const wchar_t* type;
            };
        };

        template<>
        struct range_const_iterator_<const_wchar_t_ptr_>
        {
             template< typename S >
             struct pts
             {
                 typedef const wchar_t* type;
             };
        };
    }
}

#include <boost/range/detail/begin.hpp>
#include <boost/range/detail/end.hpp>
#include <boost/range/detail/size_type.hpp>
#include <boost/range/detail/value_type.hpp>
#include <boost/range/detail/common.hpp>

namespace boost
{

    namespace range_detail
    {
        //
        // str_begin()
        //
        template<>
        struct range_begin<char_ptr_>
        {
            static char* fun( char* s )
            {
                return s;
            }
        };

        template<>
        struct range_begin<const_char_ptr_>
        {
            static const char* fun( const char* s )
            {
                return s;
            }
        };

        template<>
        struct range_begin<wchar_t_ptr_>
        {

            static wchar_t* fun( wchar_t* s )
            {
                return s;
            }
        };

        template<>
        struct range_begin<const_wchar_t_ptr_>
        {
            static const wchar_t* fun( const wchar_t* s )
            {
                return s;
            }
        };

        template< typename C >
        inline BOOST_RANGE_DEDUCED_TYPENAME range_iterator<C>::type
        str_begin( C& c )
        {
            return range_detail::range_begin< BOOST_RANGE_DEDUCED_TYPENAME
                range_detail::range<C>::type >::fun( c );
        }

        //
        // str_end()
        //

        template<>
        struct range_end<char_array_>
        {
            template< typename T, std::size_t sz >
            static T* fun( T BOOST_RANGE_ARRAY_REF()[sz] )
            {
                return boost::range_detail::array_end( boost_range_array );
            }
        };

        template<>
        struct range_end<wchar_t_array_>
        {
            template< typename T, std::size_t sz >
            static T* fun( T BOOST_RANGE_ARRAY_REF()[sz] )
            {
                return boost::range_detail::array_end( boost_range_array );
            }
        };

        template<>
        struct range_end<char_ptr_>
        {
            static char* fun( char* s )
            {
                return boost::range_detail::str_end( s );
            }
        };

        template<>
        struct range_end<const_char_ptr_>
        {
            static const char* fun( const char* s )
            {
                return boost::range_detail::str_end( s );
            }
        };

        template<>
        struct range_end<wchar_t_ptr_>
        {
            static wchar_t* fun( wchar_t* s )
            {
                return boost::range_detail::str_end( s );
            }
        };

        template<>
        struct range_end<const_wchar_t_ptr_>
        {
            static const wchar_t* fun( const wchar_t* s )
            {
                return boost::range_detail::str_end( s );
            }
        };

        template< typename C >
        inline BOOST_RANGE_DEDUCED_TYPENAME range_iterator<C>::type
        str_end( C& c )
        {
            return range_detail::range_end< BOOST_RANGE_DEDUCED_TYPENAME
                range_detail::range<C>::type >::fun( c );
        }

        //
        // size_type
        //

        template<>
        struct range_size_type_<char_array_>
        {
            template< typename A >
            struct pts
            {
                typedef std::size_t type;
            };
        };

        template<>
        struct range_size_type_<char_ptr_>
        {
            template< typename S >
            struct pts
            {
                typedef std::size_t type;
            };
        };

        template<>
        struct range_size_type_<const_char_ptr_>
        {
            template< typename S >
            struct pts
            {
                typedef std::size_t type;
            };
        };

        template<>
        struct range_size_type_<wchar_t_ptr_>
        {
            template< typename S >
            struct pts
            {
                typedef std::size_t type;
            };
        };

        template<>
        struct range_size_type_<const_wchar_t_ptr_>
        {
            template< typename S >
            struct pts
            {
                typedef std::size_t type;
            };
        };

        //
        // value_type
        //

        template<>
        struct range_value_type_<char_array_>
        {
            template< typename T >
            struct pts
            {
                typedef char type;
            };
        };

        template<>
        struct range_value_type_<char_ptr_>
        {
             template< typename S >
             struct pts
             {
                 typedef char type;
             };
        };

        template<>
        struct range_value_type_<const_char_ptr_>
        {
             template< typename S >
             struct pts
             {
                 typedef const char type;
             };
        };

        template<>
        struct range_value_type_<wchar_t_ptr_>
        {
             template< typename S >
             struct pts
             {
                 typedef wchar_t type;
             };
        };

        template<>
        struct range_value_type_<const_wchar_t_ptr_>
        {
            template< typename S >
            struct pts
            {
                typedef const wchar_t type;
            };
        };

    } // namespace 'range_detail'

} // namespace 'boost'

#endif


code:
// Boost.Range library
//
//  Copyright Thorsten Ottosen 2003-2004. 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)
//
// For more information, see http://www.boost.org/libs/range/
//

#ifndef BOOST_RANGE_DETAIL_DIFFERENCE_TYPE_HPP
#define BOOST_RANGE_DETAIL_DIFFERENCE_TYPE_HPP

#include <boost/range/detail/common.hpp>
#include <boost/iterator/iterator_traits.hpp>

//////////////////////////////////////////////////////////////////////////////
// missing partial specialization  workaround.
//////////////////////////////////////////////////////////////////////////////

namespace boost
{
    namespace range_detail
    {
        template< typename T >
        struct range_difference_type_;

        template<>
        struct range_difference_type_<std_container_>
        {
            template< typename C >
            struct pts
            {
                typedef BOOST_DEDUCED_TYPENAME C::difference_type type;
            };
        };

        template<>
        struct range_difference_type_<std_pair_>
        {
            template< typename P >
            struct pts
            {
                typedef BOOST_RANGE_DEDUCED_TYPENAME boost::iterator_difference< BOOST_DEDUCED_TYPENAME P::first_type>::type type;
            };
        };

        template<>
        struct range_difference_type_<array_>
        {
            template< typename A >
            struct pts
            {
                typedef std::ptrdiff_t type;
            };
        };

        template<>
        struct range_difference_type_<char_array_>
        {
            template< typename A >
            struct pts
            {
                typedef std::ptrdiff_t type;
            };
        };

        template<>
        struct range_difference_type_<char_ptr_>
        {
            template< typename S >
            struct pts
            {
                typedef std::ptrdiff_t type;
            };
        };

        template<>
        struct range_difference_type_<const_char_ptr_>
        {
            template< typename S >
            struct pts
            {
                typedef std::ptrdiff_t type;
            };
        };

        template<>
        struct range_difference_type_<wchar_t_ptr_>
        {
            template< typename S >
            struct pts
            {
                typedef std::ptrdiff_t type;
            };
        };

        template<>
        struct range_difference_type_<const_wchar_t_ptr_>
        {
            template< typename S >
            struct pts
            {
                typedef std::ptrdiff_t type;
            };
        };

    }

    template< typename C >
    class range_difference
    {
        typedef BOOST_RANGE_DEDUCED_TYPENAME range_detail::range<C>::type c_type;
    public:
        typedef BOOST_RANGE_DEDUCED_TYPENAME range_detail::range_difference_type_<c_type>::BOOST_NESTED_TEMPLATE pts<C>::type type;
    };

}

#endif


code:
// Boost.Range library
//
//  Copyright Thorsten Ottosen 2003-2004. 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)
//
// For more information, see http://www.boost.org/libs/range/
//

#ifndef BOOST_RANGE_DETAIL_END_HPP
#define BOOST_RANGE_DETAIL_END_HPP

#include <boost/config.hpp> // BOOST_MSVC
#include <boost/detail/workaround.hpp>

#include <boost/range/detail/implementation_help.hpp>
#include <boost/range/iterator.hpp>
#include <boost/range/detail/common.hpp>

namespace boost
{
    namespace range_detail
    {
        template< typename T >
        struct range_end;

        //////////////////////////////////////////////////////////////////////
        // default
        //////////////////////////////////////////////////////////////////////

        template<>
        struct range_end<std_container_>
        {
            template< typename C >
            static BOOST_RANGE_DEDUCED_TYPENAME range_iterator<C>::type
            fun( C& c )
            {
                return c.end();
            };
        };

        //////////////////////////////////////////////////////////////////////
        // pair
        //////////////////////////////////////////////////////////////////////

        template<>
        struct range_end<std_pair_>
        {
            template< typename P >
            static BOOST_RANGE_DEDUCED_TYPENAME range_iterator<P>::type
            fun( const P& p )
            {
                return p.second;
            }
        };

        //////////////////////////////////////////////////////////////////////
        // array
        //////////////////////////////////////////////////////////////////////

        template<>
        struct range_end<array_>
        {
            template<typename T>
            static BOOST_RANGE_DEDUCED_TYPENAME remove_extent<T>::type* fun(T& t)
            {
                return t + remove_extent<T>::size;
            }
        };

    } // namespace 'range_detail'

    namespace range_adl_barrier
    {
        template< typename C >
        inline BOOST_RANGE_DEDUCED_TYPENAME range_iterator<C>::type
        end( C& c )
        {
            return range_detail::range_end< BOOST_RANGE_DEDUCED_TYPENAME range_detail::range<C>::type >::fun( c );
        }
    } // namespace range_adl_barrier

} // namespace 'boost'

#endif


code:
// Boost.Range library
//
//  Copyright Arno Schoedl & Neil Groves 2009.
//  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)
//
// For more information, see http://www.boost.org/libs/range/
//
#ifndef BOOST_RANGE_DETAIL_EXTRACT_OPTIONAL_TYPE_HPP_INCLUDED
#define BOOST_RANGE_DETAIL_EXTRACT_OPTIONAL_TYPE_HPP_INCLUDED

#if defined(_MSC_VER)
# pragma once
#endif

#include <boost/config.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/mpl/has_xxx.hpp>

#if !defined(BOOST_MPL_CFG_NO_HAS_XXX)

// Defines extract_some_typedef<T> which exposes T::some_typedef as
// extract_some_typedef<T>::type if T::some_typedef exists. Otherwise
// extract_some_typedef<T> is empty.
#define BOOST_RANGE_EXTRACT_OPTIONAL_TYPE( a_typedef )                          \
    BOOST_MPL_HAS_XXX_TRAIT_DEF(a_typedef)                                      \
    template< typename  C, bool B = BOOST_PP_CAT(has_, a_typedef)<C>::value >   \
    struct BOOST_PP_CAT(extract_, a_typedef)                                    \
    {};                                                                         \
    template< typename C >                                                      \
    struct BOOST_PP_CAT(extract_, a_typedef)< C, true >                         \
    {                                                                           \
        typedef BOOST_DEDUCED_TYPENAME C::a_typedef type;                       \
    };

#else

#define BOOST_RANGE_EXTRACT_OPTIONAL_TYPE( a_typedef )                          \
    template< typename C >                                                      \
    struct BOOST_PP_CAT(extract_, a_typedef)                                    \
    {                                                                           \
        typedef BOOST_DEDUCED_TYPENAME C::a_typedef type;                       \
    };

#endif

#endif // include guard


code:
// Boost.Range library
//
// Copyright Neil Groves 2014.
//
// Use, modification and distribution are 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).
//
// For more information, see http://www.boost.org/libs/range/
//
#ifndef BOOST_RANGE_DETAIL_HAS_MEMBER_SIZE_HPP
#define BOOST_RANGE_DETAIL_HAS_MEMBER_SIZE_HPP

#include <boost/type_traits/is_class.hpp>
#include <boost/type_traits/is_member_function_pointer.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/cstdint.hpp>

namespace boost
{
    namespace range_detail
    {

template<class T>
class has_member_size_impl
{
private:
    template<class U, U>
    class check
    {
    };

    template<class C>
    static boost::uint8_t f(check<std::size_t(C::*)(void) const, &C::size>*);

    template<class C>
    static boost::uint16_t f(...);

public:
    static const bool value =
        (sizeof(f<T>(0)) == sizeof(boost::uint8_t));

    typedef typename mpl::if_c<
        (sizeof(f<T>(0)) == sizeof(boost::uint8_t)),
        mpl::true_,
        mpl::false_
    >::type type;
};

template<class T>
struct has_member_size
{
    typedef typename mpl::and_<
        typename is_class<T>::type,
        typename has_member_size_impl<const T>::type
    >::type type;

    static const bool value =
        is_class<T>::value && has_member_size_impl<const T>::value;
};

    } // namespace range_detail
}// namespace boost

#endif // include guard


code:
// Boost.Range library
//
//  Copyright Thorsten Ottosen 2003-2004. 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)
//
// For more information, see http://www.boost.org/libs/range/
//

#ifndef BOOST_RANGE_DETAIL_IMPLEMENTATION_HELP_HPP
#define BOOST_RANGE_DETAIL_IMPLEMENTATION_HELP_HPP

#include <boost/range/config.hpp>
#include <boost/range/detail/common.hpp>
#include <boost/type_traits/is_same.hpp>
#include <cstddef>
#include <string.h>

#ifndef BOOST_NO_CWCHAR
#include <wchar.h>
#endif

namespace boost
{
    namespace range_detail
    {
        template <typename T>
        inline void boost_range_silence_warning( const T& ) { }

        /////////////////////////////////////////////////////////////////////
        // end() help
        /////////////////////////////////////////////////////////////////////

        inline const char* str_end( const char* s, const char* )
        {
            return s + strlen( s );
        }

#ifndef BOOST_NO_CWCHAR
        inline const wchar_t* str_end( const wchar_t* s, const wchar_t* )
        {
            return s + wcslen( s );
        }
#else
        inline const wchar_t* str_end( const wchar_t* s, const wchar_t* )
        {
            if( s == 0 || s[0] == 0 )
                return s;
            while( *++s != 0 )
                ;
            return s;
        }
#endif

        template< class Char >
        inline Char* str_end( Char* s )
        {
            return const_cast<Char*>( str_end( s, s ) );
        }

        template< class T, std::size_t sz >
        inline T* array_end( T BOOST_RANGE_ARRAY_REF()[sz] )
        {
            return boost_range_array + sz;
        }

        template< class T, std::size_t sz >
        inline const T* array_end( const T BOOST_RANGE_ARRAY_REF()[sz] )
        {
            return boost_range_array + sz;
        }

        /////////////////////////////////////////////////////////////////////
        // size() help
        /////////////////////////////////////////////////////////////////////

        template< class Char >
        inline std::size_t str_size( const Char* const& s )
        {
            return str_end( s ) - s;
        }

        template< class T, std::size_t sz >
        inline std::size_t array_size( T BOOST_RANGE_ARRAY_REF()[sz] )
        {
            boost_range_silence_warning( boost_range_array );
            return sz;
        }

        template< class T, std::size_t sz >
        inline std::size_t array_size( const T BOOST_RANGE_ARRAY_REF()[sz] )
        {
            boost_range_silence_warning( boost_range_array );
            return sz;
        }

        inline bool is_same_address(const void* l, const void* r)
        {
            return l == r;
        }

        template<class T1, class T2>
        inline bool is_same_object(const T1& l, const T2& r)
        {
            return range_detail::is_same_address(&l, &r);
        }

    } // namespace 'range_detail'

} // namespace 'boost'

#endif


code:
// Boost.Range library
//
//  Copyright Neil Groves 2009. 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)
//
// Acknowledgements:
// aschoedl contributed an improvement to the determination
// of the Reference type parameter.
//
// Leonid Gershanovich reported Trac ticket 7376 about the dereference operator
// requiring identical reference types due to using the ternary if.
//
// For more information, see http://www.boost.org/libs/range/
//
#ifndef BOOST_RANGE_DETAIL_JOIN_ITERATOR_HPP_INCLUDED
#define BOOST_RANGE_DETAIL_JOIN_ITERATOR_HPP_INCLUDED

#include <iterator>
#include <boost/assert.hpp>
#include <boost/iterator/iterator_traits.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/empty.hpp>
#include <boost/range/detail/demote_iterator_traversal_tag.hpp>
#include <boost/range/value_type.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/next_prior.hpp>

namespace boost
{
    namespace range_detail
    {

template<typename Iterator1, typename Iterator2>
struct join_iterator_link
{
public:
    join_iterator_link(Iterator1 last1, Iterator2 first2)
        :    last1(last1)
        ,    first2(first2)
    {
    }

    Iterator1 last1;
    Iterator2 first2;

private:
    join_iterator_link() /* = delete */ ;
};

class join_iterator_begin_tag {};
class join_iterator_end_tag {};

template<typename Iterator1
       , typename Iterator2
       , typename Reference
>
class join_iterator_union
{
public:
    typedef Iterator1 iterator1_t;
    typedef Iterator2 iterator2_t;

    join_iterator_union() {}
    join_iterator_union(unsigned int /*selected*/, const iterator1_t& it1, const iterator2_t& it2) : m_it1(it1), m_it2(it2) {}

    iterator1_t& it1() { return m_it1; }
    const iterator1_t& it1() const { return m_it1; }

    iterator2_t& it2() { return m_it2; }
    const iterator2_t& it2() const { return m_it2; }

    Reference dereference(unsigned int selected) const
    {
        if (selected)
            return *m_it2;
        return *m_it1;
    }

    bool equal(const join_iterator_union& other, unsigned int selected) const
    {
        return selected
            ? m_it2 == other.m_it2
            : m_it1 == other.m_it1;
    }

private:
    iterator1_t m_it1;
    iterator2_t m_it2;
};

template<class Iterator, class Reference>
class join_iterator_union<Iterator, Iterator, Reference>
{
public:
    typedef Iterator iterator1_t;
    typedef Iterator iterator2_t;

    join_iterator_union() {}

    join_iterator_union(unsigned int selected, const iterator1_t& it1, const iterator2_t& it2)
        : m_it(selected ? it2 : it1)
    {
    }

    iterator1_t& it1() { return m_it; }
    const iterator1_t& it1() const { return m_it; }

    iterator2_t& it2() { return m_it; }
    const iterator2_t& it2() const { return m_it; }

    Reference dereference(unsigned int) const
    {
        return *m_it;
    }

    bool equal(const join_iterator_union& other,
               unsigned int /*selected*/) const
    {
        return m_it == other.m_it;
    }

private:
    iterator1_t m_it;
};

template<typename Iterator1
       , typename Iterator2
       , typename ValueType = typename iterator_value<Iterator1>::type
       // find least demanding, commonly supported reference type, in the order &, const&, and by-value:
       , typename Reference = typename mpl::if_c<
                !is_reference<typename iterator_reference<Iterator1>::type>::value
             || !is_reference<typename iterator_reference<Iterator2>::type>::value,
                        typename remove_const<
                            typename remove_reference<
                                typename iterator_reference<Iterator1>::type
                            >::type
                        >::type,
                        typename mpl::if_c<
                            is_const<
                                typename remove_reference<
                                    typename iterator_reference<Iterator1>::type
                                >::type
                            >::value
                            || is_const<
                                typename remove_reference<
                                    typename iterator_reference<Iterator2>::type
                                >::type
                            >::value,
                            typename add_const<
                                typename iterator_reference<Iterator1>::type
                            >::type,
                            typename iterator_reference<Iterator1>::type
                        >::type
                    >::type
       , typename Traversal = typename demote_iterator_traversal_tag<
                                  typename iterator_traversal<Iterator1>::type
                                , typename iterator_traversal<Iterator2>::type>::type
>
class join_iterator
    : public iterator_facade<join_iterator<Iterator1,Iterator2,ValueType,Reference,Traversal>, ValueType, Traversal, Reference>
{
    typedef join_iterator_link<Iterator1, Iterator2> link_t;
    typedef join_iterator_union<Iterator1, Iterator2, Reference> iterator_union;
public:
    typedef Iterator1 iterator1_t;
    typedef Iterator2 iterator2_t;

    join_iterator()
        : m_section(0u)
        , m_it(0u, iterator1_t(), iterator2_t())
        , m_link(link_t(iterator1_t(), iterator2_t()))
    {}

    join_iterator(unsigned int section, Iterator1 current1, Iterator1 last1, Iterator2 first2, Iterator2 current2)
        : m_section(section)
        , m_it(section, current1, current2)
        , m_link(link_t(last1, first2))
        {
        }

    template<typename Range1, typename Range2>
    join_iterator(Range1& r1, Range2& r2, join_iterator_begin_tag)
        : m_section(boost::empty(r1) ? 1u : 0u)
        , m_it(boost::empty(r1) ? 1u : 0u, boost::begin(r1), boost::begin(r2))
        , m_link(link_t(boost::end(r1), boost::begin(r2)))
    {
    }

    template<typename Range1, typename Range2>
    join_iterator(const Range1& r1, const Range2& r2, join_iterator_begin_tag)
        : m_section(boost::empty(r1) ? 1u : 0u)
        , m_it(boost::empty(r1) ? 1u : 0u, boost::const_begin(r1), boost::const_begin(r2))
        , m_link(link_t(boost::const_end(r1), boost::const_begin(r2)))
    {
    }

    template<typename Range1, typename Range2>
    join_iterator(Range1& r1, Range2& r2, join_iterator_end_tag)
        : m_section(1u)
        , m_it(1u, boost::end(r1), boost::end(r2))
        , m_link(link_t(boost::end(r1), boost::begin(r2)))
    {
    }

    template<typename Range1, typename Range2>
    join_iterator(const Range1& r1, const Range2& r2, join_iterator_end_tag)
        : m_section(1u)
        , m_it(1u, boost::const_end(r1), boost::const_end(r2))
        , m_link(link_t(boost::const_end(r1), boost::const_begin(r2)))
    {
    }

private:
    void increment()
    {
        if (m_section)
            ++m_it.it2();
        else
        {
            ++m_it.it1();
            if (m_it.it1() == m_link.last1)
            {
                m_it.it2() = m_link.first2;
                m_section = 1u;
            }
        }
    }

    void decrement()
    {
        if (m_section)
        {
            if (m_it.it2() == m_link.first2)
            {
                m_it.it1() = boost::prior(m_link.last1);
                m_section = 0u;
            }
            else
                --m_it.it2();
        }
        else
            --m_it.it1();
    }

    typename join_iterator::reference dereference() const
    {
        return m_it.dereference(m_section);
    }

    bool equal(const join_iterator& other) const
    {
        return m_section == other.m_section
            && m_it.equal(other.m_it, m_section);
    }

    void advance(typename join_iterator::difference_type offset)
    {
        if (m_section)
            advance_from_range2(offset);
        else
            advance_from_range1(offset);
    }

    typename join_iterator::difference_type distance_to(const join_iterator& other) const
    {
        typename join_iterator::difference_type result;
        if (m_section)
        {
            if (other.m_section)
                result = other.m_it.it2() - m_it.it2();
            else
            {
                result = (m_link.first2 - m_it.it2())
                       + (other.m_it.it1() - m_link.last1);

                BOOST_ASSERT( result <= 0 );
            }
        }
        else
        {
            if (other.m_section)
            {
                result = (m_link.last1 - m_it.it1())
                       + (other.m_it.it2() - m_link.first2);
            }
            else
                result = other.m_it.it1() - m_it.it1();
        }
        return result;
    }

    void advance_from_range2(typename join_iterator::difference_type offset)
    {
        typedef typename join_iterator::difference_type difference_t;
        BOOST_ASSERT( m_section == 1u );
        if (offset < 0)
        {
            difference_t r2_dist = m_link.first2 - m_it.it2();
            BOOST_ASSERT( r2_dist <= 0 );
            if (offset >= r2_dist)
                std::advance(m_it.it2(), offset);
            else
            {
                difference_t r1_dist = offset - r2_dist;
                BOOST_ASSERT( r1_dist <= 0 );
                m_it.it1() = m_link.last1 + r1_dist;
                m_section = 0u;
            }
        }
        else
            std::advance(m_it.it2(), offset);
    }

    void advance_from_range1(typename join_iterator::difference_type offset)
    {
        typedef typename join_iterator::difference_type difference_t;
        BOOST_ASSERT( m_section == 0u );
        if (offset > 0)
        {
            difference_t r1_dist = m_link.last1 - m_it.it1();
            BOOST_ASSERT( r1_dist >= 0 );
            if (offset < r1_dist)
                std::advance(m_it.it1(), offset);
            else
            {
                difference_t r2_dist = offset - r1_dist;
                BOOST_ASSERT( r2_dist >= 0 );
                m_it.it2() = m_link.first2 + r2_dist;
                m_section = 1u;
            }
        }
        else
            std::advance(m_it.it1(), offset);
    }

    unsigned int m_section;
    iterator_union m_it;
    link_t m_link;

    friend class ::boost::iterator_core_access;
};

    } // namespace range_detail

} // namespace boost

#endif // include guard