1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #ifndef CSV_RANGE_HXX 25 #define CSV_RANGE_HXX 26 27 #include <cstring> // for std::size_t 28 29 30 31 32 namespace csv 33 { 34 35 36 /** Represents a range of integer or iterator values. 37 38 @tpl T 39 Has to be assignable, add- and subtractable. That is: 40 either it is 41 - an integral type 42 - or a random access iterator. 43 */ 44 template <class T> 45 class range 46 { 47 public: 48 typedef T element_type; /// Provided for generic programming. 49 typedef range<T> self; 50 51 // LIFECYCLE 52 range( 53 T i_inclusiveLowerBorder, 54 T i_exclusiveUpperBorder ); 55 ~range(); 56 // INQUIRY 57 T begin() const; 58 T end() const; 59 std::size_t size() const; 60 61 bool contains( 62 T i_value ) const; 63 bool contains( 64 const self & i_other ) const; 65 bool overlaps( 66 const self & i_other ) const; 67 /// @return i_other.begin() - this->end() 68 long distance_to( 69 const self & i_other ) const; 70 private: 71 // DATA 72 T nBegin; 73 T nEnd; 74 }; 75 76 77 template <class T> 78 inline range<T> 79 make_range(T i1, T i2) 80 { 81 return range<T>(i1, i2); 82 } 83 84 template <class T> 85 inline range<typename T::const_iterator> 86 range_of(const T & i_container) 87 { 88 return make_range( i_container.begin(), 89 i_container.end() 90 ); 91 } 92 93 template <class T> 94 inline range<typename T::iterator> 95 range_of(T & io_container) 96 { 97 return make_range( io_container.begin(), 98 io_container.end() 99 ); 100 } 101 102 103 104 105 106 // IMPLEMENTATION 107 108 template <class T> 109 range<T>::range( T i_inclusiveLowerBorder, 110 T i_exclusiveUpperBorder ) 111 : nBegin(i_inclusiveLowerBorder), 112 nEnd(i_exclusiveUpperBorder) 113 { 114 csv_assert( nBegin <= nEnd 115 && "Invalid parameters for range<> constructor."); 116 } 117 118 template <class T> 119 range<T>::~range() 120 { 121 } 122 123 template <class T> 124 inline T 125 range<T>::begin() const 126 { 127 return nBegin; 128 } 129 130 template <class T> 131 inline T 132 range<T>::end() const 133 { 134 return nEnd; 135 } 136 137 template <class T> 138 inline std::size_t 139 range<T>::size() const 140 { 141 csv_assert( nBegin <= nEnd 142 && "Invalid range limits in range<>::size()."); 143 return static_cast<std::size_t>( end() - begin() ); 144 } 145 146 template <class T> 147 bool 148 range<T>::contains(T i_value ) const 149 { 150 return begin() <= i_value 151 && i_value < end(); 152 } 153 154 template <class T> 155 bool 156 range<T>::contains(const self & i_other) const 157 { 158 // This is subtle, because this would be wrong: 159 // begin() <= i_other.begin() 160 // && i_other.end() <= end(); 161 // An empty range that begins and starts at my end() 162 // must not be contained. 163 164 return contains(i_other.begin()) 165 && i_other.end() <= end(); 166 } 167 168 template <class T> 169 bool 170 range<T>::overlaps(const self & i_other) const 171 { 172 return contains(i_other.begin()) 173 || i_other.contains(begin()); 174 } 175 176 template <class T> 177 long 178 range<T>::distance_to(const self & i_other) const 179 { 180 return i_other.begin() - end(); 181 } 182 183 184 185 186 } // namespace csv 187 #endif 188