diff options
Diffstat (limited to 'include/o3tl/range.hxx')
-rw-r--r-- | include/o3tl/range.hxx | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/include/o3tl/range.hxx b/include/o3tl/range.hxx new file mode 100644 index 000000000000..a5ebacb4c6b8 --- /dev/null +++ b/include/o3tl/range.hxx @@ -0,0 +1,183 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#ifndef INCLUDED_O3TL_RANGE_HXX +#define INCLUDED_O3TL_RANGE_HXX + + +#include <cstring> // for std::size_t +#include <boost/assert.hpp> + + + +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 T> +class range +{ + public: + typedef T element_type; /// Provided for generic programming. + typedef range<T> 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 <class T> +inline range<T> +make_range(T i1, T i2) +{ + return range<T>(i1, i2); +} + +template <class T> +inline range<typename T::const_iterator> +range_of(const T & i_container) +{ + return make_range( i_container.begin(), + i_container.end() + ); +} + +template <class T> +inline range<typename T::iterator> +range_of(T & io_container) +{ + return make_range( io_container.begin(), + io_container.end() + ); +} + + + + + +// IMPLEMENTATION + +template <class T> +range<T>::range( T i_inclusiveLowerBorder, + T i_exclusiveUpperBorder ) + : nBegin(i_inclusiveLowerBorder), + nEnd(i_exclusiveUpperBorder) +{ + BOOST_ASSERT( nBegin <= nEnd + && "Invalid parameters for range<> constructor."); +} + +template <class T> +range<T>::~range() +{ +} + +template <class T> +inline T +range<T>::begin() const +{ + return nBegin; +} + +template <class T> +inline T +range<T>::end() const +{ + return nEnd; +} + +template <class T> +inline std::size_t +range<T>::size() const +{ + BOOST_ASSERT( nBegin <= nEnd + && "Invalid range limits in range<>::size()."); + return static_cast<std::size_t>( end() - begin() ); +} + +template <class T> +bool +range<T>::contains(T i_value ) const +{ + return begin() <= i_value + && i_value < end(); +} + +template <class T> +bool +range<T>::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 <class T> +bool +range<T>::overlaps(const self & i_other) const +{ + return contains(i_other.begin()) + || i_other.contains(begin()); +} + +template <class T> +long +range<T>::distance_to(const self & i_other) const +{ + return i_other.begin() - end(); +} + + + +} // namespace o3tl +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |