Chris@16: // Boost string_algo library collection_traits.hpp header file -----------------------// Chris@16: Chris@16: // Copyright Pavol Droba 2002-2003. Use, modification and Chris@16: // distribution is subject to the Boost Software License, Version Chris@16: // 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: // See http://www.boost.org for updates, documentation, and revision history. Chris@16: Chris@16: #ifndef BOOST_RANGE_STRING_DETAIL_COLLECTION_TRAITS_HPP Chris@16: #define BOOST_RANGE_STRING_DETAIL_COLLECTION_TRAITS_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: // Container traits implementation --------------------------------------------------------- Chris@16: Chris@16: namespace boost { Chris@16: namespace algorithm { Chris@16: namespace detail { Chris@16: Chris@16: // Default collection traits ----------------------------------------------------------------- Chris@16: Chris@16: // Default collection helper Chris@16: /* Chris@16: Wraps std::container compliant containers Chris@16: */ Chris@16: template< typename ContainerT > Chris@16: struct default_container_traits Chris@16: { Chris@101: typedef typename ContainerT::value_type value_type; Chris@101: typedef typename ContainerT::iterator iterator; Chris@101: typedef typename ContainerT::const_iterator const_iterator; Chris@101: typedef typename Chris@16: ::boost::mpl::if_< ::boost::is_const, Chris@16: const_iterator, Chris@16: iterator Chris@16: >::type result_iterator; Chris@101: typedef typename ContainerT::difference_type difference_type; Chris@101: typedef typename ContainerT::size_type size_type; Chris@16: Chris@16: // static operations Chris@16: template< typename C > Chris@16: static size_type size( const C& c ) Chris@16: { Chris@16: return c.size(); Chris@16: } Chris@16: Chris@16: template< typename C > Chris@16: static bool empty( const C& c ) Chris@16: { Chris@16: return c.empty(); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING Chris@16: Chris@16: template< typename C > Chris@16: static iterator begin( C& c ) Chris@16: { Chris@16: return c.begin(); Chris@16: } Chris@16: Chris@16: template< typename C > Chris@16: static const_iterator begin( const C& c ) Chris@16: { Chris@16: return c.begin(); Chris@16: } Chris@16: Chris@16: template< typename C > Chris@16: static iterator end( C& c ) Chris@16: { Chris@16: return c.end(); Chris@16: } Chris@16: Chris@16: template< typename C > Chris@16: static const_iterator end( const C& c ) Chris@16: { Chris@16: return c.end(); Chris@16: } Chris@16: Chris@16: #else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING Chris@16: Chris@16: template< typename C > Chris@16: static result_iterator begin( C& c ) Chris@16: { Chris@16: return c.begin(); Chris@16: } Chris@16: Chris@16: template< typename C > Chris@16: static result_iterator end( C& c ) Chris@16: { Chris@16: return c.end(); Chris@16: } Chris@16: Chris@16: #endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING Chris@16: Chris@16: }; Chris@16: Chris@16: template Chris@16: struct default_container_traits_selector Chris@16: { Chris@16: typedef default_container_traits type; Chris@16: }; Chris@16: Chris@16: // Pair container traits --------------------------------------------------------------------- Chris@101: Chris@101: typedef double yes_type; Chris@101: typedef char no_type; Chris@101: Chris@16: // pair selector Chris@16: template< typename T, typename U > Chris@16: yes_type is_pair_impl( const std::pair* ); Chris@16: no_type is_pair_impl( ... ); Chris@16: Chris@16: template struct is_pair Chris@16: { Chris@16: private: Chris@16: static T* t; Chris@16: public: Chris@16: BOOST_STATIC_CONSTANT( bool, value= Chris@16: sizeof(is_pair_impl(t))==sizeof(yes_type) ); Chris@16: }; Chris@16: Chris@16: // pair helper Chris@16: template< typename PairT > Chris@16: struct pair_container_traits Chris@16: { Chris@101: typedef typename PairT::first_type element_type; Chris@16: Chris@101: typedef typename ::boost::detail:: Chris@16: iterator_traits::value_type value_type; Chris@16: typedef std::size_t size_type; Chris@101: typedef typename ::boost::detail:: Chris@16: iterator_traits::difference_type difference_type; Chris@16: Chris@16: typedef element_type iterator; Chris@16: typedef element_type const_iterator; Chris@16: typedef element_type result_iterator; Chris@16: Chris@16: // static operations Chris@16: template< typename P > Chris@16: static size_type size( const P& p ) Chris@16: { Chris@16: difference_type diff = std::distance( p.first, p.second ); Chris@16: if ( diff < 0 ) Chris@16: return 0; Chris@16: else Chris@16: return diff; Chris@16: } Chris@16: Chris@16: template< typename P > Chris@16: static bool empty( const P& p ) Chris@16: { Chris@16: return p.first==p.second; Chris@16: } Chris@16: Chris@16: template< typename P > Chris@16: static const_iterator begin( const P& p ) Chris@16: { Chris@16: return p.first; Chris@16: } Chris@16: Chris@16: template< typename P > Chris@16: static const_iterator end( const P& p ) Chris@16: { Chris@16: return p.second; Chris@16: } Chris@16: }; // 'pair_container_helper' Chris@16: Chris@16: template Chris@16: struct pair_container_traits_selector Chris@16: { Chris@16: typedef pair_container_traits type; Chris@16: }; Chris@16: Chris@16: // Array container traits --------------------------------------------------------------- Chris@16: Chris@16: // array traits ( partial specialization ) Chris@16: template< typename T > Chris@16: struct array_traits; Chris@16: Chris@16: template< typename T, std::size_t sz > Chris@16: struct array_traits Chris@16: { Chris@16: // typedef Chris@16: typedef T* iterator; Chris@16: typedef const T* const_iterator; Chris@16: typedef T value_type; Chris@16: typedef std::size_t size_type; Chris@16: typedef std::ptrdiff_t difference_type; Chris@16: Chris@16: // size of the array ( static ); Chris@16: BOOST_STATIC_CONSTANT( size_type, array_size = sz ); Chris@16: }; Chris@16: Chris@16: Chris@16: // array length resolving Chris@16: /* Chris@16: Lenght of string contained in a static array could Chris@16: be different from the size of the array. Chris@16: For string processing we need the length without Chris@16: terminating 0. Chris@16: Chris@16: Therefore, the length is calculated for char and wchar_t Chris@16: using char_traits, rather then simply returning Chris@16: the array size. Chris@16: */ Chris@16: template< typename T > Chris@16: struct array_length_selector Chris@16: { Chris@16: template< typename TraitsT > Chris@16: struct array_length Chris@16: { Chris@101: typedef typename Chris@16: TraitsT::size_type size_type; Chris@16: Chris@16: BOOST_STATIC_CONSTANT( Chris@16: size_type, Chris@16: array_size=TraitsT::array_size ); Chris@16: Chris@16: template< typename A > Chris@16: static size_type length( const A& ) Chris@16: { Chris@16: return array_size; Chris@16: } Chris@16: Chris@16: template< typename A > Chris@16: static bool empty( const A& ) Chris@16: { Chris@16: return array_size==0; Chris@16: } Chris@16: }; Chris@16: }; Chris@16: Chris@16: // specialization for char Chris@16: template<> Chris@16: struct array_length_selector Chris@16: { Chris@16: template< typename TraitsT > Chris@16: struct array_length Chris@16: { Chris@101: typedef typename Chris@16: TraitsT::size_type size_type; Chris@16: Chris@16: template< typename A > Chris@16: static size_type length( const A& a ) Chris@16: { Chris@16: if ( a==0 ) Chris@16: return 0; Chris@16: else Chris@16: return std::char_traits::length(a); Chris@16: } Chris@16: Chris@16: template< typename A > Chris@16: static bool empty( const A& a ) Chris@16: { Chris@16: return a==0 || a[0]==0; Chris@16: } Chris@16: }; Chris@16: }; Chris@16: Chris@16: // specialization for wchar_t Chris@16: template<> Chris@16: struct array_length_selector Chris@16: { Chris@16: template< typename TraitsT > Chris@16: struct array_length Chris@16: { Chris@101: typedef typename Chris@16: TraitsT::size_type size_type; Chris@16: Chris@16: template< typename A > Chris@16: static size_type length( const A& a ) Chris@16: { Chris@16: if ( a==0 ) Chris@16: return 0; Chris@16: else Chris@16: return std::char_traits::length(a); Chris@16: } Chris@16: Chris@16: template< typename A > Chris@16: static bool empty( const A& a ) Chris@16: { Chris@16: return a==0 || a[0]==0; Chris@16: } Chris@16: }; Chris@16: }; Chris@16: Chris@16: template< typename T > Chris@16: struct array_container_traits Chris@16: { Chris@16: private: Chris@16: // resolve array traits Chris@16: typedef array_traits traits_type; Chris@16: Chris@16: public: Chris@101: typedef typename Chris@16: traits_type::value_type value_type; Chris@101: typedef typename Chris@16: traits_type::iterator iterator; Chris@101: typedef typename Chris@16: traits_type::const_iterator const_iterator; Chris@101: typedef typename Chris@16: traits_type::size_type size_type; Chris@101: typedef typename Chris@16: traits_type::difference_type difference_type; Chris@16: Chris@101: typedef typename Chris@16: ::boost::mpl::if_< ::boost::is_const, Chris@16: const_iterator, Chris@16: iterator Chris@16: >::type result_iterator; Chris@16: Chris@16: private: Chris@16: // resolve array size Chris@101: typedef typename Chris@16: ::boost::remove_cv::type char_type; Chris@101: typedef typename Chris@16: array_length_selector:: Chris@16: BOOST_NESTED_TEMPLATE array_length array_length_type; Chris@16: Chris@16: public: Chris@16: BOOST_STATIC_CONSTANT( size_type, array_size = traits_type::array_size ); Chris@16: Chris@16: // static operations Chris@16: template< typename A > Chris@16: static size_type size( const A& a ) Chris@16: { Chris@16: return array_length_type::length(a); Chris@16: } Chris@16: Chris@16: template< typename A > Chris@16: static bool empty( const A& a ) Chris@16: { Chris@16: return array_length_type::empty(a); Chris@16: } Chris@16: Chris@16: Chris@16: #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING Chris@16: Chris@16: template< typename A > Chris@16: static iterator begin( A& a ) Chris@16: { Chris@16: return a; Chris@16: } Chris@16: Chris@16: template< typename A > Chris@16: static const_iterator begin( const A& a ) Chris@16: { Chris@16: return a; Chris@16: } Chris@16: Chris@16: template< typename A > Chris@16: static iterator end( A& a ) Chris@16: { Chris@16: return a+array_length_type::length(a); Chris@16: } Chris@16: Chris@16: template< typename A > Chris@16: static const_iterator end( const A& a ) Chris@16: { Chris@16: return a+array_length_type::length(a); Chris@16: } Chris@16: Chris@16: #else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING Chris@16: Chris@16: template< typename A > Chris@16: static result_iterator begin( A& a ) Chris@16: { Chris@16: return a; Chris@16: } Chris@16: Chris@16: template< typename A > Chris@16: static result_iterator end( A& a ) Chris@16: { Chris@16: return a+array_length_type::length(a); Chris@16: } Chris@16: Chris@16: #endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING Chris@16: Chris@16: }; Chris@16: Chris@16: template Chris@16: struct array_container_traits_selector Chris@16: { Chris@16: typedef array_container_traits type; Chris@16: }; Chris@16: Chris@16: // Pointer container traits --------------------------------------------------------------- Chris@16: Chris@16: template Chris@16: struct pointer_container_traits Chris@16: { Chris@101: typedef typename Chris@16: ::boost::remove_pointer::type value_type; Chris@16: Chris@101: typedef typename Chris@16: ::boost::remove_cv::type char_type; Chris@16: typedef ::std::char_traits char_traits; Chris@16: Chris@16: typedef value_type* iterator; Chris@16: typedef const value_type* const_iterator; Chris@16: typedef std::ptrdiff_t difference_type; Chris@16: typedef std::size_t size_type; Chris@16: Chris@101: typedef typename Chris@16: ::boost::mpl::if_< ::boost::is_const, Chris@16: const_iterator, Chris@16: iterator Chris@16: >::type result_iterator; Chris@16: Chris@16: // static operations Chris@16: template< typename P > Chris@16: static size_type size( const P& p ) Chris@16: { Chris@16: if ( p==0 ) Chris@16: return 0; Chris@16: else Chris@16: return char_traits::length(p); Chris@16: } Chris@16: Chris@16: template< typename P > Chris@16: static bool empty( const P& p ) Chris@16: { Chris@16: return p==0 || p[0]==0; Chris@16: } Chris@16: Chris@16: #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING Chris@16: Chris@16: template< typename P > Chris@16: static iterator begin( P& p ) Chris@16: { Chris@16: return p; Chris@16: } Chris@16: Chris@16: template< typename P > Chris@16: static const_iterator begin( const P& p ) Chris@16: { Chris@16: return p; Chris@16: } Chris@16: Chris@16: template< typename P > Chris@16: static iterator end( P& p ) Chris@16: { Chris@16: if ( p==0 ) Chris@16: return p; Chris@16: else Chris@16: return p+char_traits::length(p); Chris@16: } Chris@16: Chris@16: template< typename P > Chris@16: static const_iterator end( const P& p ) Chris@16: { Chris@16: if ( p==0 ) Chris@16: return p; Chris@16: else Chris@16: return p+char_traits::length(p); Chris@16: } Chris@16: Chris@16: #else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING Chris@16: Chris@16: template< typename P > Chris@16: static result_iterator begin( P& p ) Chris@16: { Chris@16: return p; Chris@16: } Chris@16: Chris@16: template< typename P > Chris@16: static result_iterator end( P& p ) Chris@16: { Chris@16: if ( p==0 ) Chris@16: return p; Chris@16: else Chris@16: return p+char_traits::length(p); Chris@16: } Chris@16: Chris@16: #endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING Chris@16: }; Chris@16: Chris@16: template Chris@16: struct pointer_container_traits_selector Chris@16: { Chris@16: typedef pointer_container_traits type; Chris@16: }; Chris@16: Chris@16: } // namespace detail Chris@16: } // namespace algorithm Chris@16: } // namespace boost Chris@16: Chris@16: Chris@16: #endif // BOOST_STRING_DETAIL_COLLECTION_HPP