forked from boostorg/range
*** empty log message ***
[SVN r27190]
This commit is contained in:
266
include/boost/range/detail/collection_traits.hpp
Executable file
266
include/boost/range/detail/collection_traits.hpp
Executable file
@ -0,0 +1,266 @@
|
|||||||
|
// 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/algorithm/string/config.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 BOOST_STRING_TYPENAME ::boost::mpl::eval_if<
|
||||||
|
::boost::algorithm::detail::is_pair<T>,
|
||||||
|
detail::pair_container_traits_selector<T>,
|
||||||
|
BOOST_STRING_TYPENAME ::boost::mpl::eval_if<
|
||||||
|
::boost::is_array<T>,
|
||||||
|
detail::array_container_traits_selector<T>,
|
||||||
|
BOOST_STRING_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 BOOST_STRING_TYPENAME
|
||||||
|
container_helper_type::value_type value_type;
|
||||||
|
//! Size type
|
||||||
|
typedef BOOST_STRING_TYPENAME
|
||||||
|
container_helper_type::size_type size_type;
|
||||||
|
//! Iterator type
|
||||||
|
typedef BOOST_STRING_TYPENAME
|
||||||
|
container_helper_type::iterator iterator;
|
||||||
|
//! Const iterator type
|
||||||
|
typedef BOOST_STRING_TYPENAME
|
||||||
|
container_helper_type::const_iterator const_iterator;
|
||||||
|
//! Result iterator type ( iterator of const_iterator, depending on the constness of the container )
|
||||||
|
typedef BOOST_STRING_TYPENAME
|
||||||
|
container_helper_type::result_iterator result_iterator;
|
||||||
|
//! Difference type
|
||||||
|
typedef BOOST_STRING_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 BOOST_STRING_TYPENAME collection_traits<C>::value_type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Container difference trait
|
||||||
|
/*!
|
||||||
|
Extract the container's difference type
|
||||||
|
*/
|
||||||
|
template< typename C >
|
||||||
|
struct difference_type_of
|
||||||
|
{
|
||||||
|
typedef BOOST_STRING_TYPENAME collection_traits<C>::difference_type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Container iterator trait
|
||||||
|
/*!
|
||||||
|
Extract the container's iterator type
|
||||||
|
*/
|
||||||
|
template< typename C >
|
||||||
|
struct iterator_of
|
||||||
|
{
|
||||||
|
typedef BOOST_STRING_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 BOOST_STRING_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 BOOST_STRING_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 BOOST_STRING_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 BOOST_STRING_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 BOOST_STRING_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 BOOST_STRING_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 BOOST_STRING_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 BOOST_STRING_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 BOOST_STRING_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
|
621
include/boost/range/detail/collection_traits_detail.hpp
Executable file
621
include/boost/range/detail/collection_traits_detail.hpp
Executable file
@ -0,0 +1,621 @@
|
|||||||
|
// 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 <boost/algorithm/string/config.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>
|
||||||
|
#include <boost/algorithm/string/yes_no_type.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 BOOST_STRING_TYPENAME ContainerT::value_type value_type;
|
||||||
|
typedef BOOST_STRING_TYPENAME ContainerT::iterator iterator;
|
||||||
|
typedef BOOST_STRING_TYPENAME ContainerT::const_iterator const_iterator;
|
||||||
|
typedef BOOST_STRING_TYPENAME
|
||||||
|
::boost::mpl::if_< ::boost::is_const<ContainerT>,
|
||||||
|
const_iterator,
|
||||||
|
iterator
|
||||||
|
>::type result_iterator;
|
||||||
|
typedef BOOST_STRING_TYPENAME ContainerT::difference_type difference_type;
|
||||||
|
typedef BOOST_STRING_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 ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
// 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 BOOST_STRING_TYPENAME PairT::first_type element_type;
|
||||||
|
|
||||||
|
typedef BOOST_STRING_TYPENAME ::boost::detail::
|
||||||
|
iterator_traits<element_type>::value_type value_type;
|
||||||
|
typedef std::size_t size_type;
|
||||||
|
typedef BOOST_STRING_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 ---------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
// 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 );
|
||||||
|
};
|
||||||
|
|
||||||
|
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
|
||||||
|
// array traits ( no partial specialization )
|
||||||
|
/*
|
||||||
|
without parial specialization we are able to
|
||||||
|
provide support only for a limited number of
|
||||||
|
types. Currently the primitive numeric types
|
||||||
|
are supported
|
||||||
|
*/
|
||||||
|
template< typename T, typename BaseT >
|
||||||
|
struct array_traits_impl
|
||||||
|
{
|
||||||
|
typedef BaseT value_type;
|
||||||
|
typedef BaseT* iterator;
|
||||||
|
typedef const BaseT* const_iterator;
|
||||||
|
typedef std::size_t size_type;
|
||||||
|
typedef std::ptrdiff_t difference_type;
|
||||||
|
|
||||||
|
// size of the array
|
||||||
|
BOOST_STATIC_CONSTANT( size_type, array_size = sizeof(T)/sizeof(BaseT) );
|
||||||
|
};
|
||||||
|
|
||||||
|
template< typename T, typename BaseT >
|
||||||
|
struct array_traits_impl_selector
|
||||||
|
{
|
||||||
|
typedef array_traits_impl<T,BaseT> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct array_traits_void
|
||||||
|
{
|
||||||
|
typedef void type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template< typename T, typename BaseT >
|
||||||
|
struct array_traits_cv_selector
|
||||||
|
{
|
||||||
|
typedef BOOST_STRING_TYPENAME
|
||||||
|
::boost::mpl::eval_if<
|
||||||
|
::boost::is_convertible<T,BaseT*>,
|
||||||
|
array_traits_impl_selector<T,BaseT>,
|
||||||
|
::boost::mpl::eval_if<
|
||||||
|
::boost::is_convertible<T,const BaseT*>,
|
||||||
|
array_traits_impl_selector<T, const BaseT>,
|
||||||
|
::boost::mpl::eval_if<
|
||||||
|
::boost::is_convertible<T, volatile BaseT*>,
|
||||||
|
array_traits_impl_selector<T, volatile BaseT>,
|
||||||
|
array_traits_impl_selector<T, const volatile BaseT>
|
||||||
|
>
|
||||||
|
>
|
||||||
|
>::type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
struct array_traits_select
|
||||||
|
{
|
||||||
|
template< typename T1, typename T2 >
|
||||||
|
struct apply
|
||||||
|
{
|
||||||
|
typedef BOOST_STRING_TYPENAME
|
||||||
|
::boost::mpl::eval_if<
|
||||||
|
::boost::is_convertible<T,const volatile T2*>,
|
||||||
|
array_traits_cv_selector<T,T2>,
|
||||||
|
::boost::mpl::identity<T1> >::type type;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
struct array_traits_selector
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
// supported array base types
|
||||||
|
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
|
||||||
|
typedef BOOST_STRING_TYPENAME
|
||||||
|
::boost::mpl::vector10<
|
||||||
|
wchar_t,
|
||||||
|
#else // BOOST_NO_INTRINSIC_WCHAR_T
|
||||||
|
typedef BOOST_STRING_TYPENAME
|
||||||
|
::boost::mpl::vector9<
|
||||||
|
#endif // BOOST_NO_INTRINSIC_WCHAR_T
|
||||||
|
char,
|
||||||
|
signed char,
|
||||||
|
unsigned char,
|
||||||
|
signed short,
|
||||||
|
unsigned short,
|
||||||
|
signed int,
|
||||||
|
unsigned int,
|
||||||
|
signed long,
|
||||||
|
unsigned long
|
||||||
|
>::type array_base_types;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef BOOST_STRING_TYPENAME
|
||||||
|
::boost::mpl::fold<
|
||||||
|
array_base_types,
|
||||||
|
::boost::algorithm::detail::array_traits_void,
|
||||||
|
::boost::algorithm::detail::array_traits_select<T> >::type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
struct array_traits
|
||||||
|
{
|
||||||
|
typedef BOOST_STRING_TYPENAME
|
||||||
|
array_traits_selector<T>::type traits_type;
|
||||||
|
|
||||||
|
typedef BOOST_STRING_TYPENAME
|
||||||
|
traits_type::value_type value_type;
|
||||||
|
typedef BOOST_STRING_TYPENAME
|
||||||
|
traits_type::iterator iterator;
|
||||||
|
typedef BOOST_STRING_TYPENAME
|
||||||
|
traits_type::const_iterator const_iterator;
|
||||||
|
typedef BOOST_STRING_TYPENAME
|
||||||
|
traits_type::size_type size_type;
|
||||||
|
typedef BOOST_STRING_TYPENAME
|
||||||
|
traits_type::difference_type difference_type;
|
||||||
|
|
||||||
|
BOOST_STATIC_CONSTANT( size_type, array_size = traits_type::array_size );
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
|
||||||
|
// array lenght resolving
|
||||||
|
/*
|
||||||
|
Lenght of string contained in a static array could
|
||||||
|
be different from the size of the array.
|
||||||
|
For string processing we need the lenght without
|
||||||
|
terminating 0.
|
||||||
|
|
||||||
|
Therefore, the lenght is calulated 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 BOOST_STRING_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 BOOST_STRING_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 BOOST_STRING_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 BOOST_STRING_TYPENAME
|
||||||
|
traits_type::value_type value_type;
|
||||||
|
typedef BOOST_STRING_TYPENAME
|
||||||
|
traits_type::iterator iterator;
|
||||||
|
typedef BOOST_STRING_TYPENAME
|
||||||
|
traits_type::const_iterator const_iterator;
|
||||||
|
typedef BOOST_STRING_TYPENAME
|
||||||
|
traits_type::size_type size_type;
|
||||||
|
typedef BOOST_STRING_TYPENAME
|
||||||
|
traits_type::difference_type difference_type;
|
||||||
|
|
||||||
|
typedef BOOST_STRING_TYPENAME
|
||||||
|
::boost::mpl::if_< ::boost::is_const<T>,
|
||||||
|
const_iterator,
|
||||||
|
iterator
|
||||||
|
>::type result_iterator;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// resolve array size
|
||||||
|
typedef BOOST_STRING_TYPENAME
|
||||||
|
::boost::remove_cv<value_type>::type char_type;
|
||||||
|
typedef BOOST_STRING_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 BOOST_STRING_TYPENAME
|
||||||
|
::boost::remove_pointer<T>::type value_type;
|
||||||
|
|
||||||
|
typedef BOOST_STRING_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 BOOST_STRING_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
|
Reference in New Issue
Block a user