extent: add range-for adapter for extent points
This commit is contained in:
parent
543da8f15e
commit
464c703ffd
96
extent.cpp
96
extent.cpp
@ -22,6 +22,7 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
using util::extent;
|
using util::extent;
|
||||||
|
using util::extent_range;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
@ -119,11 +120,97 @@ const extent<S,T> extent<S,T>::MIN { 0 };
|
|||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
template <size_t S, typename T>
|
template <size_t S, typename T>
|
||||||
const extent<S,T> extent<S,T>::MAX {
|
const extent<S,T> extent<S,T>::MAX
|
||||||
|
{
|
||||||
std::numeric_limits<T>::max ()
|
std::numeric_limits<T>::max ()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
template <size_t S, typename T>
|
||||||
|
extent_range<S,T>::extent_range (extent<S,T> _target):
|
||||||
|
m_target (_target)
|
||||||
|
{ ; }
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
template <size_t S, typename T>
|
||||||
|
typename extent_range<S,T>::iterator
|
||||||
|
extent_range<S,T>::begin (void) const
|
||||||
|
{
|
||||||
|
return iterator (m_target, util::point<S,T> (0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
template <size_t S, typename T>
|
||||||
|
typename extent_range<S,T>::iterator
|
||||||
|
extent_range<S,T>::end (void) const
|
||||||
|
{
|
||||||
|
util::point<S,T> cursor (0);
|
||||||
|
cursor[S-1] = m_target[S-1];
|
||||||
|
|
||||||
|
return iterator (m_target, cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
template <size_t S, typename T>
|
||||||
|
extent_range<S,T>::iterator::iterator (extent<S,T> _target, util::point<S,T> _cursor):
|
||||||
|
m_cursor (_cursor),
|
||||||
|
m_target (_target)
|
||||||
|
{
|
||||||
|
static_assert (std::is_integral<T>::value, "range stepping size is ill-defined for non-integral types");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
template <size_t S, typename T>
|
||||||
|
util::point<S,T>
|
||||||
|
extent_range<S,T>::iterator::operator* (void) const
|
||||||
|
{
|
||||||
|
return m_cursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
template <size_t S, typename T>
|
||||||
|
typename extent_range<S,T>::iterator&
|
||||||
|
extent_range<S,T>::iterator::operator++ (void)
|
||||||
|
{
|
||||||
|
++m_cursor[0];
|
||||||
|
|
||||||
|
for (size_t i = 0; i < S - 1; ++i) {
|
||||||
|
if (m_cursor[i] != m_target[i])
|
||||||
|
break;
|
||||||
|
|
||||||
|
m_cursor[i] = 0;
|
||||||
|
m_cursor[i+1]++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
template <size_t S, typename T>
|
||||||
|
bool
|
||||||
|
extent_range<S,T>::iterator::operator== (const iterator &rhs) const
|
||||||
|
{
|
||||||
|
return m_cursor == rhs.m_cursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
template <size_t S, typename T>
|
||||||
|
bool
|
||||||
|
extent_range<S,T>::iterator::operator!= (const iterator &rhs) const
|
||||||
|
{
|
||||||
|
return m_cursor != rhs.m_cursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
namespace debug {
|
namespace debug {
|
||||||
template <size_t S, typename T>
|
template <size_t S, typename T>
|
||||||
@ -173,4 +260,11 @@ namespace util {
|
|||||||
INSTANTIATE(uint64_t)
|
INSTANTIATE(uint64_t)
|
||||||
INSTANTIATE(float)
|
INSTANTIATE(float)
|
||||||
INSTANTIATE(double)
|
INSTANTIATE(double)
|
||||||
|
|
||||||
|
template struct extent_range<2,uint16_t>;
|
||||||
|
template struct extent_range<3,uint16_t>;
|
||||||
|
template struct extent_range<2,uint32_t>;
|
||||||
|
template struct extent_range<3,uint32_t>;
|
||||||
|
template struct extent_range<2,uint64_t>;
|
||||||
|
template struct extent_range<3,uint64_t>;
|
||||||
}
|
}
|
||||||
|
35
extent.hpp
35
extent.hpp
@ -56,6 +56,33 @@ namespace util {
|
|||||||
static const extent MIN;
|
static const extent MIN;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <size_t S, typename T>
|
||||||
|
struct extent_range {
|
||||||
|
public:
|
||||||
|
struct iterator : public std::iterator<std::forward_iterator_tag, point<S,T>, size_t> {
|
||||||
|
public:
|
||||||
|
iterator (extent<S,T>, util::point<S,T>);
|
||||||
|
|
||||||
|
point<S,T> operator* () const;
|
||||||
|
iterator& operator++ (void);
|
||||||
|
|
||||||
|
bool operator!= (const iterator &rhs) const;
|
||||||
|
bool operator== (const iterator &rhs) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
point<S,T> m_cursor;
|
||||||
|
extent<S,T> m_target;
|
||||||
|
};
|
||||||
|
|
||||||
|
extent_range (extent<S,T> target);
|
||||||
|
|
||||||
|
iterator begin (void) const;
|
||||||
|
iterator end (void) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
extent<S,T> m_target;
|
||||||
|
};
|
||||||
|
|
||||||
// convenience typedefs
|
// convenience typedefs
|
||||||
template <typename T> using extent2 = extent<2,T>;
|
template <typename T> using extent2 = extent<2,T>;
|
||||||
template <typename T> using extent3 = extent<3,T>;
|
template <typename T> using extent3 = extent<3,T>;
|
||||||
@ -68,6 +95,14 @@ namespace util {
|
|||||||
typedef extent3<size_t> extent3u;
|
typedef extent3<size_t> extent3u;
|
||||||
typedef extent3<float> extent3f;
|
typedef extent3<float> extent3f;
|
||||||
|
|
||||||
|
template <typename T> using extent_range2 = extent_range<2,T>;
|
||||||
|
template <typename T> using extent_range3 = extent_range<3,T>;
|
||||||
|
|
||||||
|
using extent_range2u = extent_range2<typename extent2u::value_type>;
|
||||||
|
using extent_range2i = extent_range2<typename extent2i::value_type>;
|
||||||
|
|
||||||
|
using extent_range3u = extent_range2<typename extent3u::value_type>;
|
||||||
|
|
||||||
template <size_t S, typename T>
|
template <size_t S, typename T>
|
||||||
std::ostream& operator<< (std::ostream&, util::extent<S,T>);
|
std::ostream& operator<< (std::ostream&, util::extent<S,T>);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "extent.hpp"
|
#include "extent.hpp"
|
||||||
#include "tap.hpp"
|
#include "tap.hpp"
|
||||||
|
#include "types.hpp"
|
||||||
|
|
||||||
int
|
int
|
||||||
main (void)
|
main (void)
|
||||||
@ -12,5 +13,21 @@ main (void)
|
|||||||
tap.expect_eq (lo, hi.contracted (2), "extent scalar contraction by value");
|
tap.expect_eq (lo, hi.contracted (2), "extent scalar contraction by value");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
static const util::point2u EXPECTED[] = {
|
||||||
|
{ 0, 0 }, { 1, 0 }, { 2, 0 },
|
||||||
|
{ 0, 1 }, { 1, 1 }, { 2, 1 },
|
||||||
|
{ 0, 2 }, { 1, 2 }, { 2, 2 },
|
||||||
|
};
|
||||||
|
|
||||||
|
size_t offset = 0;
|
||||||
|
unsigned success = 0;
|
||||||
|
|
||||||
|
for (auto p: util::extent_range2u ({3, 3}))
|
||||||
|
success += EXPECTED[offset++] == p ? 1 : 0;
|
||||||
|
|
||||||
|
tap.expect (success == elems (EXPECTED), "extent_range2u iteration");
|
||||||
|
}
|
||||||
|
|
||||||
return tap.status ();
|
return tap.status ();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user