/////////////////////////////////////////////////////////////////////////////// // // Copyright (c) 2018 martysama0134. All rights reserved. // // This code is licensed under the MIT License (MIT). // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /////////////////////////////////////////////////////////////////////////////// #pragma once #include #include namespace msl { //! @brief range_iterator used for range template class range_iterator { T m_value_{}; public: explicit range_iterator(T value) : m_value_{value} {} T operator*() { return m_value_; } range_iterator & operator++() { ++m_value_; return *this; } range_iterator & operator--() { --m_value_; return *this; } range_iterator operator++(int) { ++m_value_; return *this; } range_iterator operator--(int) { --m_value_; return *this; } bool operator!=(range_iterator & r) { return m_value_ != *r; } }; //! @brief range mostly used in for-range (no memory allocation) template class range { range_iterator m_min_{0}; range_iterator m_max_; public: explicit range(T max) : m_max_{max} {} range(T min, T max) : m_min_{min}, m_max_{max} {} range_iterator begin() { if (*m_min_ == *m_max_) return m_max_; return m_min_; } range_iterator end() { return m_max_; } }; using crange = range; using irange = range; using llrange = range; using frange = range; using drange = range; //! @brief xrange mostly used in for-range (it uses std::vector with n=((max-min)/diff) elements) template class xrange { std::vector m_vec_; public: explicit xrange(T max) : xrange(0, max, 1) {} xrange(T min, T max) : xrange(min, max, 1) {} xrange(T min, T max, T diff) { if (min >= max) throw std::runtime_error("xrange min >= max"); if (diff <= 0) throw std::runtime_error("xrange diff <= 0"); // 4x faster than emplace_back m_vec_.resize(static_cast((max - min) / diff)); for (auto & e : m_vec_) { e += min; min += diff; } } auto begin() { return std::begin(m_vec_); } auto end() { return std::end(m_vec_); } }; using xcrange = xrange; using xirange = xrange; using xllrange = xrange; using xfrange = xrange; using xdrange = xrange; } // namespace msl