/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ #ifndef INCLUDED_O3TL_RANGE_HXX #define INCLUDED_O3TL_RANGE_HXX #include // for std::size_t #include namespace o3tl { /** Represents a range of integer or iterator values. @tpl T Has to be assignable, add- and subtractable. That is: either it is - an integral type - or a random access iterator. */ template class range { public: typedef T element_type; /// Provided for generic programming. typedef range self; // LIFECYCLE range( T i_inclusiveLowerBorder, T i_exclusiveUpperBorder ); ~range(); // INQUIRY T begin() const; T end() const; std::size_t size() const; bool contains( T i_value ) const; bool contains( const self & i_other ) const; bool overlaps( const self & i_other ) const; /// @return i_other.begin() - this->end() long distance_to( const self & i_other ) const; private: // DATA T nBegin; T nEnd; }; template inline range make_range(T i1, T i2) { return range(i1, i2); } template inline range range_of(const T & i_container) { return make_range( i_container.begin(), i_container.end() ); } template inline range range_of(T & io_container) { return make_range( io_container.begin(), io_container.end() ); } // IMPLEMENTATION template range::range( T i_inclusiveLowerBorder, T i_exclusiveUpperBorder ) : nBegin(i_inclusiveLowerBorder), nEnd(i_exclusiveUpperBorder) { BOOST_ASSERT( nBegin <= nEnd && "Invalid parameters for range<> constructor."); } template range::~range() { } template inline T range::begin() const { return nBegin; } template inline T range::end() const { return nEnd; } template inline std::size_t range::size() const { BOOST_ASSERT( nBegin <= nEnd && "Invalid range limits in range<>::size()."); return static_cast( end() - begin() ); } template bool range::contains(T i_value ) const { return begin() <= i_value && i_value < end(); } template bool range::contains(const self & i_other) const { // This is subtle, because this would be wrong: // begin() <= i_other.begin() // && i_other.end() <= end(); // An empty range that begins and starts at my end() // must not be contained. return contains(i_other.begin()) && i_other.end() <= end(); } template bool range::overlaps(const self & i_other) const { return contains(i_other.begin()) || i_other.contains(begin()); } template long range::distance_to(const self & i_other) const { return i_other.begin() - end(); } } // namespace o3tl #endif