/* * Licensed 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. * * Copyright 2010-2017 Danny Robson */ #ifndef CRUFT_UTIL_EXTENT_HPP #define CRUFT_UTIL_EXTENT_HPP #include "coord/fwd.hpp" #include "coord/base.hpp" #include "vector.hpp" #include "point.hpp" #include namespace util { /** * A pure n-dimensional size, without positioning */ template struct extent : public ::util::coord::base> { using ::util::coord::base>::base; extent () = default; explicit extent (::util::vector); constexpr T area (void) const { return std::accumulate (std::begin (this->data), std::end (this->data), T {1}, std::multiplies ()); } constexpr T diameter (void) const { return static_cast ( std::sqrt ( std::accumulate (std::begin (this->data), std::end (this->data), T {0}, [] (auto a, auto b) { return a + b * b; }) ) ); } template constexpr U aspect (void) const { return static_cast (this->w) / this->h; } /// tests whether a point would lie within: /// region { origin, *this }, inclusive of borders. /// /// included for parity with util::region. constexpr bool inclusive (util::point p) const { return all (p >= T{0} && p <= *this); } /// tests whether a point would like within: /// region { origin, *this }, exclusive of the bottom-right border /// included for parity with util::region constexpr bool exclusive (point p) const { return all (p >= T{0} && p < *this); } ::util::extent expanded (::util::vector) const; ::util::extent expanded (T) const; ::util::extent contracted (::util::vector) const; ::util::extent contracted (T) const; bool empty (void) const; static constexpr ::util::extent max (void) { return extent { std::numeric_limits::max () }; } static constexpr ::util::extent min (void) { return extent { 0 }; } }; template struct extent_range { public: struct iterator : public std::iterator< std::forward_iterator_tag, ::util::point, size_t > { public: iterator (::util::extent, ::util::point); point operator* () const; iterator& operator++ (void); bool operator!= (const iterator &rhs) const; bool operator== (const iterator &rhs) const; private: point m_cursor; extent m_target; }; explicit extent_range (extent target); iterator begin (void) const; iterator end (void) const; private: extent m_target; }; /////////////////////////////////////////////////////////////////////////// template extent_range make_range (extent e) { return extent_range {e}; } /////////////////////////////////////////////////////////////////////////// // convenience typedefs template using extent2 = extent<2,T>; template using extent3 = extent<3,T>; template using extentu = extent; template using extenti = extent; template using extentf = extent; template using extentd = extent; typedef extent2 extent2i; typedef extent2 extent2u; typedef extent2 extent2f; typedef extent2 extent2d; typedef extent3 extent3u; typedef extent3 extent3f; //------------------------------------------------------------------------- template using extent_range2 = extent_range<2,T>; template using extent_range3 = extent_range<3,T>; using extent_range2u = extent_range2; using extent_range2i = extent_range2; using extent_range3u = extent_range2; } #endif