lean cpp library
A lean C++ library providing efficient utility classes for high-performance C++ applications.
|
00001 /*****************************************************/ 00002 /* lean Strings (c) Tobias Zirr 2011 */ 00003 /*****************************************************/ 00004 00005 #ifndef LEAN_STRINGS_NULLTERMINATED_RANGE 00006 #define LEAN_STRINGS_NULLTERMINATED_RANGE 00007 00008 #include "../lean.h" 00009 #include "../meta/strip.h" 00010 #include "../meta/enable_if.h" 00011 #include "char_traits.h" 00012 #include "nullterminated.h" 00013 00014 namespace lean 00015 { 00016 namespace strings 00017 { 00018 00021 template < class Char, class Traits = char_traits<typename strip_const<Char>::type> > 00022 class nullterminated_range_implicit : public nullterminated_implicit<Char, Traits> 00023 { 00024 typedef nullterminated_implicit<Char, Traits> base_type; 00025 00026 public: 00028 typedef typename base_type::value_type value_type; 00029 00031 typedef typename base_type::size_type size_type; 00033 typedef typename base_type::difference_type difference_type; 00034 00036 typedef typename base_type::pointer pointer; 00038 typedef typename base_type::const_pointer const_pointer; 00040 typedef typename base_type::reference reference; 00042 typedef typename base_type::const_reference const_reference; 00043 00045 typedef typename base_type::pointer iterator; 00047 typedef typename base_type::const_iterator const_iterator; 00048 00050 typedef typename base_type::traits_type traits_type; 00051 00052 private: 00054 static LEAN_INLINE void assert_null_terminated(const_pointer end) 00055 { 00056 LEAN_ASSERT(end); 00057 LEAN_ASSERT(traits_type::null(*end)); 00058 } 00059 00061 static LEAN_INLINE const_pointer first_non_null(const_pointer a, const_pointer b) 00062 { 00063 return (a) ? a : b; 00064 } 00065 00066 protected: 00067 const_pointer m_end; 00068 00069 public: 00071 LEAN_INLINE nullterminated_range_implicit(const nullterminated_implicit<Char, Traits> &right) 00072 : base_type(right), 00073 m_end(right.end()) 00074 { 00075 assert_null_terminated(m_end); 00076 } 00078 LEAN_INLINE nullterminated_range_implicit(const_pointer begin) 00079 : base_type(begin), 00080 m_end(base_type::end()) 00081 { 00082 assert_null_terminated(m_end); 00083 } 00085 LEAN_INLINE nullterminated_range_implicit(const_pointer begin, const_pointer end) 00086 : base_type(begin), 00087 m_end(end) 00088 { 00089 assert_null_terminated(m_end); 00090 } 00092 template <class Compatible> 00093 LEAN_INLINE nullterminated_range_implicit(const Compatible &from, 00094 typename enable_if<is_nullterminated_compatible<Compatible, value_type, traits_type>::value, const void*>::type = nullptr) 00095 : base_type(from), 00096 m_end( 00097 first_non_null( 00098 nullterminated_compatible<Compatible, value_type, traits_type>::from(from, base_type::begin()), 00099 base_type::end() ) 00100 ) 00101 { 00102 assert_null_terminated(m_end); 00103 } 00104 00106 LEAN_INLINE bool empty() const { return (m_begin == m_end); } 00108 LEAN_INLINE size_type length() const { return m_end - m_begin; } 00110 LEAN_INLINE size_type size() const { return length(); } 00112 LEAN_INLINE size_type count() const { return traits_type::count(m_begin, m_end); } 00113 00115 LEAN_INLINE const_iterator end() const { return m_end; } 00116 00118 LEAN_INLINE void swap(nullterminated_range_implicit& right) 00119 { 00120 base_type::swap(right); 00121 const_pointer right_end = right.m_end; 00122 right.m_end = m_end; 00123 m_end = right_end; 00124 } 00125 00127 template <class Compatible> 00128 Compatible to() const 00129 { 00130 typedef typename assert_nullterminated_compatible< 00131 Compatible, 00132 value_type, traits_type 00133 >::type assert_compatible; 00134 return nullterminated_compatible<Compatible, value_type, traits_type>::to(m_begin, m_end); 00135 } 00136 }; 00137 00139 template < class Char, class Traits = char_traits<typename strip_const<Char>::type> > 00140 class nullterminated_range : public nullterminated_range_implicit<Char, Traits> 00141 { 00142 public: 00144 typedef nullterminated_range_implicit<Char, Traits> implicit_type; 00145 00147 explicit LEAN_INLINE nullterminated_range(typename implicit_type::const_pointer begin) 00148 : implicit_type(begin) { } 00150 LEAN_INLINE nullterminated_range(typename implicit_type::const_pointer begin, typename implicit_type::const_pointer end) 00151 : implicit_type(begin, end) { } 00153 template <class Compatible> 00154 explicit LEAN_INLINE nullterminated_range(const Compatible &from, 00155 typename enable_if<is_nullterminated_compatible<Compatible, value_type, traits_type>::value, const void*>::type = nullptr) 00156 : implicit_type(from) { } 00158 explicit LEAN_INLINE nullterminated_range(const implicit_type &right) 00159 : implicit_type(right) { } 00160 00162 explicit LEAN_INLINE nullterminated_range(const nullterminated_implicit<Char, Traits> &right) 00163 : implicit_type(right) { } 00165 LEAN_INLINE nullterminated_range(const nullterminated<Char, Traits> &right) 00166 : implicit_type(right) { } 00167 00169 LEAN_INLINE operator nullterminated<Char, Traits>() const 00170 { 00171 return nullterminated<Char, Traits>(*this); 00172 } 00173 }; 00174 00176 template <class Char, class Traits> 00177 LEAN_INLINE nullterminated_range<Char, Traits> make_ntr(const nullterminated_range_implicit<Char, Traits> &range) 00178 { 00179 return nullterminated_range<Char, Traits>(range); 00180 } 00182 template <class Char> 00183 LEAN_INLINE nullterminated_range<Char> make_ntr(const Char *range) 00184 { 00185 return nullterminated_range<Char>(range); 00186 } 00188 template <class Char, class Compatible> 00189 LEAN_INLINE typename enable_if< 00190 is_nullterminated_compatible<Compatible, Char, typename nullterminated_range<Char>::traits_type>::value, 00191 nullterminated_range<Char> 00192 >::type make_ntr(const Compatible &compatible) 00193 { 00194 return nullterminated_range<Char>(compatible); 00195 } 00196 00198 template <class Char, class Traits> 00199 LEAN_INLINE bool operator ==(const nullterminated_range_implicit<Char, Traits>& left, const nullterminated_range_implicit<Char, Traits>& right) 00200 { 00201 return (left.length() == right.length()) && nullterminated<Char, Traits>::traits_type::equal(left.c_str(), right.c_str()); 00202 } 00203 template <class Char, class Traits, class Compatible> 00204 LEAN_INLINE typename enable_if<is_nullterminated_convertible<Compatible, Char, Traits>::value, bool>::type 00205 operator ==(const nullterminated_range_implicit<Char, Traits>& left, const Compatible& right) { return left == make_ntr<Char, Traits>(right); } 00206 template <class Char, class Traits, class Compatible> 00207 LEAN_INLINE typename enable_if<is_nullterminated_convertible<Compatible, Char, Traits>::value, bool>::type 00208 operator ==(const Compatible& left, const nullterminated_range_implicit<Char, Traits>& right) { return make_ntr<Char, Traits>(left) == right; } 00209 00211 template <class Char, class Traits> 00212 LEAN_INLINE bool operator !=(const nullterminated_range_implicit<Char, Traits>& left, const nullterminated_range_implicit<Char, Traits>& right) 00213 { 00214 return !(left == right); 00215 } 00216 template <class Char, class Traits, class Compatible> 00217 LEAN_INLINE typename enable_if<is_nullterminated_convertible<Compatible, Char, Traits>::value, bool>::type 00218 operator !=(const nullterminated_range_implicit<Char, Traits>& left, const Compatible& right) { return left != make_ntr<Char, Traits>(right); } 00219 template <class Char, class Traits, class Compatible> 00220 LEAN_INLINE typename enable_if<is_nullterminated_convertible<Compatible, Char, Traits>::value, bool>::type 00221 operator !=(const Compatible& left, const nullterminated_range_implicit<Char, Traits>& right) { return make_ntr<Char, Traits>(left) != right; } 00222 00224 template <class Char, class Traits> 00225 LEAN_INLINE bool operator <(const nullterminated_range_implicit<Char, Traits>& left, const nullterminated_range_implicit<Char, Traits>& right) 00226 { 00227 return nullterminated<Char, Traits>::traits_type::less(left.c_str(), right.c_str()); 00228 } 00229 template <class Char, class Traits, class Compatible> 00230 LEAN_INLINE typename enable_if<is_nullterminated_convertible<Compatible, Char, Traits>::value, bool>::type 00231 operator <(const nullterminated_range_implicit<Char, Traits>& left, const Compatible& right) { return left < make_ntr<Char, Traits>(right); } 00232 template <class Char, class Traits, class Compatible> 00233 LEAN_INLINE typename enable_if<is_nullterminated_convertible<Compatible, Char, Traits>::value, bool>::type 00234 operator <(const Compatible& left, const nullterminated_range_implicit<Char, Traits>& right) { return make_ntr<Char, Traits>(left) < right; } 00235 00237 template <class Char, class Traits> 00238 LEAN_INLINE bool operator >(const nullterminated_range_implicit<Char, Traits>& left, const nullterminated_range_implicit<Char, Traits>& right) 00239 { 00240 return (right < left); 00241 } 00242 template <class Char, class Traits, class Compatible> 00243 LEAN_INLINE typename enable_if<is_nullterminated_convertible<Compatible, Char, Traits>::value, bool>::type 00244 operator >(const nullterminated_range_implicit<Char, Traits>& left, const Compatible& right) { return left > make_ntr<Char, Traits>(right); } 00245 template <class Char, class Traits, class Compatible> 00246 LEAN_INLINE typename enable_if<is_nullterminated_convertible<Compatible, Char, Traits>::value, bool>::type 00247 operator >(const Compatible& left, const nullterminated_range_implicit<Char, Traits>& right) { return make_ntr<Char, Traits>(left) > right; } 00248 00250 template <class Char, class Traits> 00251 LEAN_INLINE bool operator <=(const nullterminated_range_implicit<Char, Traits>& left, const nullterminated_range_implicit<Char, Traits>& right) 00252 { 00253 return !(right < left); 00254 } 00255 template <class Char, class Traits, class Compatible> 00256 LEAN_INLINE typename enable_if<is_nullterminated_convertible<Compatible, Char, Traits>::value, bool>::type 00257 operator <=(const nullterminated_range_implicit<Char, Traits>& left, const Compatible& right) { return left <= make_ntr<Char, Traits>(right); } 00258 template <class Char, class Traits, class Compatible> 00259 LEAN_INLINE typename enable_if<is_nullterminated_convertible<Compatible, Char, Traits>::value, bool>::type 00260 operator <=(const Compatible& left, const nullterminated_range_implicit<Char, Traits>& right) { return make_ntr<Char, Traits>(left) <= right; } 00261 00263 template <class Char, class Traits> 00264 LEAN_INLINE bool operator >=(const nullterminated_range_implicit<Char, Traits>& left, const nullterminated_range_implicit<Char, Traits>& right) 00265 { 00266 return !(left < right); 00267 } 00268 template <class Char, class Traits, class Compatible> 00269 LEAN_INLINE typename enable_if<is_nullterminated_convertible<Compatible, Char, Traits>::value, bool>::type 00270 operator >=(const nullterminated_range_implicit<Char, Traits>& left, const Compatible& right) { return left >= make_ntr<Char, Traits>(right); } 00271 template <class Char, class Traits, class Compatible> 00272 LEAN_INLINE typename enable_if<is_nullterminated_convertible<Compatible, Char, Traits>::value, bool>::type 00273 operator >=(const Compatible& left, const nullterminated_range_implicit<Char, Traits>& right) { return make_ntr<Char, Traits>(left) >= right; } 00274 00276 template <class Char, class Traits> 00277 LEAN_INLINE void swap(nullterminated_range_implicit<Char, Traits>& left, nullterminated_range_implicit<Char, Traits>& right) 00278 { 00279 left.swap(right); 00280 } 00281 00282 } // namespace 00283 00284 using strings::nullterminated_range_implicit; 00285 using strings::nullterminated_range; 00286 00287 using strings::make_ntr; 00288 00289 } // namespace 00290 00291 #endif