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_RANGE 00006 #define LEAN_STRINGS_RANGE 00007 00008 #include "../lean.h" 00009 #include "../meta/strip.h" 00010 #include "../meta/type_traits.h" 00011 #include "../meta/enable_if.h" 00012 #include <iterator> 00013 00014 namespace lean 00015 { 00016 namespace strings 00017 { 00018 00020 template <class Iterator> 00021 class range 00022 { 00023 private: 00024 Iterator m_begin; 00025 Iterator m_end; 00026 00027 public: 00029 typedef Iterator iterator; 00031 typedef Iterator const_iterator; 00032 00034 LEAN_INLINE range() 00035 : m_begin(), m_end() { } 00037 LEAN_INLINE range(iterator begin, iterator end) 00038 : m_begin(begin), m_end(end) { } 00039 00041 LEAN_INLINE void assign(iterator begin, iterator end) 00042 { 00043 m_begin = begin; 00044 m_end = end; 00045 } 00046 00048 LEAN_INLINE bool empty() const { return (m_begin == m_end); } 00050 LEAN_INLINE size_t size() const { return m_end - m_begin; } 00051 00053 LEAN_INLINE iterator& begin() { return m_begin; } 00055 LEAN_INLINE iterator begin() const { return m_begin; } 00057 LEAN_INLINE iterator& end() { return m_end; } 00059 LEAN_INLINE iterator end() const { return m_end; } 00060 00062 LEAN_INLINE typename std::iterator_traits<iterator>::reference operator [](size_t n) const { return *(begin() + n); } 00063 }; 00064 00065 00067 template <class Iterator> 00068 LEAN_INLINE range<Iterator> make_range(Iterator begin, Iterator end) 00069 { 00070 return range<Iterator>(begin, end); 00071 } 00072 00074 template <class Char> 00075 LEAN_INLINE range<Char*> make_char_range(Char *nts) 00076 { 00077 return range<Char*>( 00078 nts, 00079 nts + std::char_traits<typename strip_modifiers<Char>::type>::length(nts) ); 00080 } 00082 template <class Range> 00083 LEAN_INLINE Range& make_char_range(Range &range) { return range; } 00084 00085 00087 template <class Class, class Range> 00088 LEAN_INLINE Class from_range(const Range &range) 00089 { 00090 return Class(range.begin(), range.end()); 00091 } 00092 00093 template <class String> 00094 struct string_traits; 00095 00097 template <class String, class Range> 00098 LEAN_INLINE String string_from_range(const Range &range) 00099 { 00100 return string_traits<String>::construct(range.begin(), range.end()); 00101 } 00102 00103 namespace impl 00104 { 00105 LEAN_DEFINE_HAS_TYPE(iterator); 00106 } 00107 00109 template <class Type> 00110 struct is_range 00111 { 00113 static const bool value = impl::has_type_iterator<Type>::value; 00114 }; 00115 00117 template <class Range, class Type> 00118 struct enable_if_range : public enable_if<is_range<Range>::value, Type> { }; 00120 template <class Range, class Type> 00121 struct enable_if_not_range : public enable_if<!is_range<Range>::value, Type> { }; 00123 template <class Range1, class Range2, class Type> 00124 struct enable_if_range2 : public enable_if<is_range<Range1>::value && is_range<Range2>::value, Type> { }; 00126 template <class Range1, class Range2, class Type> 00127 struct enable_if_not_range2 : public enable_if<!is_range<Range1>::value || !is_range<Range2>::value, Type> { }; 00128 00130 template <class Chars1> 00131 struct range_char_type; 00132 template <class Char> 00133 struct range_char_type<Char*> { typedef typename strip_modifiers<Char>::type type; }; 00134 00136 template <class Chars1, class Chars2> 00137 struct range_char_type2; 00138 template <class Char, class Chars2> 00139 struct range_char_type2<Char*, Chars2> { typedef typename strip_modifiers<Char>::type type; }; 00140 template <class Chars1, class Char> 00141 struct range_char_type2<Chars1, Char*> { typedef typename strip_modifiers<Char>::type type; }; 00142 template <class Char1, class Char2> 00143 struct range_char_type2<Char1*, Char2*> { typedef typename strip_modifiers<Char1>::type type; }; 00144 00145 } // namespace 00146 00147 using strings::range; 00148 using strings::make_range; 00149 using strings::make_char_range; 00150 using strings::from_range; 00151 using strings::string_from_range; 00152 using strings::is_range; 00153 using strings::enable_if_range; 00154 using strings::enable_if_not_range; 00155 using strings::enable_if_range2; 00156 using strings::enable_if_not_range2; 00157 using strings::range_char_type; 00158 using strings::range_char_type2; 00159 00160 } // namespace 00161 00162 #endif