lean cpp library
A lean C++ library providing efficient utility classes for high-performance C++ applications.
range.h
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