diff -r 792876306489 -r 4dd5bde4e777 sources/range.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sources/range.h Wed Dec 10 19:17:00 2014 +0200 @@ -0,0 +1,240 @@ +/* + Copyright 2014 Teemu Piippo + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#pragma once +#include +#include + +// +// ------------------------------------------------------------------------------------------------- +// + +template +class Range +{ + T m_a; + T m_b; + T m_step; + +public: + struct Iterator + { + T value; + T step; + inline METHOD operator*() -> T&; + inline METHOD operator== (const Iterator& other) const -> bool; + inline METHOD operator!= (const Iterator& other) const -> bool; + inline METHOD operator++() -> Iterator&; + }; + + Range (const T& a, const T& b, const T& step = 1); + Range(); + + METHOD begin() const -> Iterator; + METHOD end() const -> Iterator; + METHOD min() const -> T; + METHOD max() const -> T; + METHOD check_bounds() -> void; + METHOD contains (const T& c) const -> bool; + METHOD contains_exclusive (const T& c) const -> bool; + METHOD overlaps (Range const& other) const -> bool; + METHOD operator== (Range const& other) const -> bool; + METHOD operator!= (Range const& other) const -> bool; +}; + +// +// ------------------------------------------------------------------------------------------------- +// + +template inline METHOD +Range::Iterator::operator*() -> T& +{ + return value; +} + +// +// ------------------------------------------------------------------------------------------------- +// + +template inline METHOD +Range::Iterator::operator== (const Iterator& other) const -> bool +{ + return value == other.value; +} + +// +// ------------------------------------------------------------------------------------------------- +// + +template inline METHOD +Range::Iterator::operator!= (const Iterator& other) const -> bool +{ + return value != other.value; +} + +// +// ------------------------------------------------------------------------------------------------- +// + +template inline METHOD +Range::Iterator::operator++() -> Iterator& +{ + value += step; + return *this; +} + +// +// ------------------------------------------------------------------------------------------------- +// + +template +Range::Range (const T& a, const T& b, const T& step) : + m_a (a), + m_b (b), + m_step (step) +{ + check_bounds(); +} + +// +// ------------------------------------------------------------------------------------------------- +// + +template +Range::Range() : + m_a (T()), + m_b (T()) {} + +// +// ------------------------------------------------------------------------------------------------- +// + +template METHOD +Range::check_bounds() -> void +{ + if (m_b < m_a) + std::swap (m_a, m_b); +} + +// +// ------------------------------------------------------------------------------------------------- +// + +template METHOD +Range::contains (const T& c) const -> bool +{ + return (c >= m_a) and (c <= m_b); +} + +// +// ------------------------------------------------------------------------------------------------- +// + +template METHOD +Range::contains_exclusive (const T& c) const -> bool +{ + return (c > m_a) and (c < m_b); +} + +// +// ------------------------------------------------------------------------------------------------- +// + +template METHOD +Range::overlaps (Range const& other) const -> bool +{ + return contains (other.m_a) or contains (other.m_b); +} + +// +// ------------------------------------------------------------------------------------------------- +// + +template METHOD +Range::operator== (Range const& other) const -> bool +{ + return m_a == other.m_a and m_b == other.m_b; +} + +// +// ------------------------------------------------------------------------------------------------- +// + +template METHOD +Range::operator!= (Range const& other) const -> bool +{ + return not operator== (other); +} + +// +// ------------------------------------------------------------------------------------------------- +// + +template METHOD +Range::min() const -> T +{ + return m_a; +} + +// +// ------------------------------------------------------------------------------------------------- +// + +template METHOD +Range::max() const -> T +{ + return m_b; +} + +// +// ------------------------------------------------------------------------------------------------- +// + +template METHOD +Range::begin() const -> Iterator +{ + Iterator it; + it.value = min(); + it.step = m_step; + return it; +} + +// +// ------------------------------------------------------------------------------------------------- +// + +template METHOD +Range::end() const -> Iterator +{ + Iterator it; + it.value = max() + 1; + it.step = m_step; + return it; +}