summaryrefslogtreecommitdiffstats
blob: b1ac67e9b326e98426d1782845fc2af63c473409 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
//  Boost string_algo library sequence_traits.hpp header file  ---------------------------//

//  Copyright Pavol Droba 2002-2003.
//
// Distributed under the Boost Software License, Version 1.0.
//    (See accompanying file LICENSE_1_0.txt or copy at
//          http://www.boost.org/LICENSE_1_0.txt)

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

#ifndef BOOST_STRING_SEQUENCE_TRAITS_HPP
#define BOOST_STRING_SEQUENCE_TRAITS_HPP

#include <boost/config.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/algorithm/string/yes_no_type.hpp>

/*! \file
    Traits defined in this header are used by various algorithms to achieve
    better performance for specific containers.
    Traits provide fail-safe defaults. If a container supports some of these
    features, it is possible to specialize the specific trait for this container.
    For lacking compilers, it is possible of define an override for a specific tester
    function.

    Due to a language restriction, it is not currently possible to define specializations for
    stl containers without including the corresponding header. To decrease the overhead
    needed by this inclusion, user can selectively include a specialization
    header for a specific container. They are located in boost/algorithm/string/stl
    directory. Alternatively she can include boost/algorithm/string/std_collection_traits.hpp
    header which contains specializations for all stl containers.
*/

namespace boost {
    namespace algorithm {

//  sequence traits  -----------------------------------------------//

#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION

        //! Native replace tester
        /*!
            Declare an override of this tester function with return
            type boost::string_algo::yes_type for a sequence with this property.

            \return yes_type if the container has basic_string like native replace
            method.
        */
        no_type has_native_replace_tester(...);

        //! Stable iterators tester
        /*!
            Declare an override of this tester function with return
            type boost::string_algo::yes_type for a sequence with this property.

            \return yes_type if the sequence's insert/replace/erase methods do not invalidate
            existing iterators.
        */
        no_type has_stable_iterators_tester(...);

        //! const time insert tester
        /*!
            Declare an override of this tester function with return
            type boost::string_algo::yes_type for a sequence with this property.

            \return yes_type if the sequence's insert method is working in constant time
        */
        no_type has_const_time_insert_tester(...);

        //! const time erase tester
        /*!
            Declare an override of this tester function with return
            type boost::string_algo::yes_type for a sequence with this property.

            \return yes_type if the sequence's erase method is working in constant time
        */
        no_type has_const_time_erase_tester(...);

#endif //BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION

        //! Native replace trait
        /*!
            This trait specifies that the sequence has \c std::string like replace method
        */
        template< typename T >
        class has_native_replace
        {

#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
        private:
            static T* t;
        public:
            BOOST_STATIC_CONSTANT(bool, value=(
                sizeof(has_native_replace_tester(t))==sizeof(yes_type) ) );
#else  // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
        public:
#    if BOOST_WORKAROUND( __IBMCPP__, <= 600 )
            enum { value = false };
#    else
            BOOST_STATIC_CONSTANT(bool, value=false);
#    endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 )
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION


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


        //! Stable iterators trait
        /*!
            This trait specifies that the sequence has stable iterators. It means
            that operations like insert/erase/replace do not invalidate iterators.
        */
        template< typename T >
        class has_stable_iterators
        {
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
        private:
            static T* t;
        public:
            BOOST_STATIC_CONSTANT(bool, value=(
                sizeof(has_stable_iterators_tester(t))==sizeof(yes_type) ) );
#else  // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
        public:
#    if BOOST_WORKAROUND( __IBMCPP__, <= 600 )
            enum { value = false };
#    else
            BOOST_STATIC_CONSTANT(bool, value=false);
#    endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 )
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION

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


        //! Const time insert trait
        /*!
            This trait specifies that the sequence's insert method has
            constant time complexity.
        */
        template< typename T >
        class has_const_time_insert
        {
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
        private:
            static T* t;
        public:
            BOOST_STATIC_CONSTANT(bool, value=(
                sizeof(has_const_time_insert_tester(t))==sizeof(yes_type) ) );
#else  // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
        public:
#    if BOOST_WORKAROUND( __IBMCPP__, <= 600 )
            enum { value = false };
#    else
            BOOST_STATIC_CONSTANT(bool, value=false);
#    endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 )
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION

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


        //! Const time erase trait
        /*!
            This trait specifies that the sequence's erase method has
            constant time complexity.
        */
        template< typename T >
        class has_const_time_erase
        {
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
        private:
            static T* t;
        public:
            BOOST_STATIC_CONSTANT(bool, value=(
                sizeof(has_const_time_erase_tester(t))==sizeof(yes_type) ) );
#else  // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
        public:
#    if BOOST_WORKAROUND( __IBMCPP__, <= 600 )
            enum { value = false };
#    else
            BOOST_STATIC_CONSTANT(bool, value=false);
#    endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 )
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION

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

    } // namespace algorithm
} // namespace boost


#endif  // BOOST_STRING_SEQUENCE_TRAITS_HPP