Add support for custom dimension type.

Also remove overloads of operator[] and use a template instead.
This commit is contained in:
Michele Santullo 2015-08-17 13:34:17 +02:00
parent 2b2d0a3219
commit 981ec02afd
2 changed files with 34 additions and 65 deletions

View file

@ -29,10 +29,16 @@
#include <limits>
namespace vwr {
#if !defined(VWR_DIM_TYPE)
typedef std::size_t dim_type;
#else
typedef VWR_DIM_TYPE dim_type;
#endif
template <typename V>
struct VectorWrapperInfo;
template <typename V, std::size_t S=VectorWrapperInfo<V>::dimensions>
template <typename V, dim_type S=VectorWrapperInfo<V>::dimensions>
class Vec;
namespace implem {
@ -42,12 +48,12 @@ namespace vwr {
define_has_method(get_at, GetAt);
define_has_enum(cast_ignore_trailing_properties, CastIgnoreTrailingProperties);
template <typename V1, typename V2, std::size_t D>
template <typename V1, typename V2, dim_type D>
Vec<V1>& assign ( Vec<V1, D>& parLeft, const Vec<V2, D>& parRight );
template <typename V>
Vec<V>& assign_same_type ( Vec<V>& parLeft, const Vec<V>& parRight );
template <typename T, std::size_t I> struct get_offset_enum_from_index;
template <typename T, dim_type I> struct get_offset_enum_from_index;
template <typename T> struct get_offset_enum_from_index<T, 0> {
enum { value = VectorWrapperInfo<T>::offset_x };
};
@ -61,7 +67,7 @@ namespace vwr {
enum { value = VectorWrapperInfo<T>::offset_w };
};
template <typename T, std::size_t S=VectorWrapperInfo<T>::dimensions> struct min_offset {
template <typename T, dim_type S=VectorWrapperInfo<T>::dimensions> struct min_offset {
enum {
value = (
static_cast<int>(get_offset_enum_from_index<T, S-1>::value) < static_cast<int>(min_offset<T, S-1>::value) ?
@ -77,7 +83,7 @@ namespace vwr {
template <
typename T,
typename U,
std::size_t S=(
dim_type S=(
static_cast<int>(VectorWrapperInfo<T>::dimensions) < static_cast<int>(VectorWrapperInfo<U>::dimensions) ?
static_cast<int>(VectorWrapperInfo<T>::dimensions)
:
@ -151,14 +157,10 @@ namespace vwr {
VecBase ( scalar_type parX, scalar_type parY, Args... parArgs );
~VecBase ( void ) = default;
scalar_type& operator[] ( int32_t parIndex );
scalar_type& operator[] ( int64_t parIndex );
scalar_type& operator[] ( uint32_t parIndex );
scalar_type& operator[] ( uint64_t parIndex );
const scalar_type& operator[] ( int32_t parIndex ) const;
const scalar_type& operator[] ( int64_t parIndex ) const;
const scalar_type& operator[] ( uint32_t parIndex ) const;
const scalar_type& operator[] ( uint64_t parIndex ) const;
template <typename I>
scalar_type& operator[] ( I parIndex );
template <typename I>
const scalar_type& operator[] ( I parIndex ) const;
vector_type& data ( void ) { return m_wrapped; }
const vector_type& data ( void ) const { return m_wrapped; }
@ -181,7 +183,7 @@ namespace vwr {
vector_type m_wrapped;
};
template <typename T, std::size_t S=VectorWrapperInfo<T>::dimensions>
template <typename T, dim_type S=VectorWrapperInfo<T>::dimensions>
struct offsets_array_wrapper {
template <std::size_t... I>
offsets_array_wrapper ( const bt::index_seq<I...>& );
@ -193,19 +195,19 @@ namespace vwr {
class VecGetter;
template <typename T>
struct VecGetter<T, true> {
static typename VectorWrapperInfo<T>::scalar_type& get_at ( T& parVec, std::size_t parIndex );
static typename VectorWrapperInfo<T>::scalar_type& get_at ( T& parVec, dim_type parIndex );
};
template <typename T>
struct VecGetter<T, false> {
private:
static_assert(HasGetAtMethod<VectorWrapperInfo<T>>::value, "You must provide a get_at() static method for this vector_type");
typedef typename VectorWrapperInfo<T>::scalar_type scalar_type;
using return_type = decltype(std::declval<VectorWrapperInfo<T>>().get_at(std::declval<std::size_t>(), std::declval<T&>()));
using return_type = decltype(std::declval<VectorWrapperInfo<T>>().get_at(std::declval<dim_type>(), std::declval<T&>()));
static_assert(not std::is_rvalue_reference<return_type>::value, "rvalue ref return types not implemented");
static_assert(std::is_lvalue_reference<return_type>::value, "Read-only vectors not implemented");
public:
static typename VectorWrapperInfo<T>::scalar_type& get_at ( T& parVec, std::size_t parIndex );
static typename VectorWrapperInfo<T>::scalar_type& get_at ( T& parVec, dim_type parIndex );
};
template <typename V, bool Enabled> struct Vec1Promotion;
@ -261,7 +263,7 @@ namespace vwr {
lower_vector_type yz ( void ) const;
};
template <typename V, std::size_t D>
template <typename V, dim_type D>
struct VecAccessors;
//Workaround for visual studio - VecAccessors<V, 3> should inherit from
@ -305,7 +307,7 @@ namespace vwr {
bool operator_op ( const T& parLeft, const Vec<V>& parRight );
} //namespace implem
template <typename V, std::size_t S>
template <typename V, dim_type S>
class Vec : public implem::VecBase<V> {
public:
enum {

View file

@ -42,57 +42,24 @@ namespace vwr {
VecGetter<V>::get_at(m_wrapped, 1) = parY;
const scalar_type args[sizeof...(Args)] = {parArgs...};
for (std::size_t z = 0; z < sizeof...(Args); ++z) {
for (dim_type z = 0; z < sizeof...(Args); ++z) {
VecGetter<V>::get_at(m_wrapped, z + 2) = args[z];
}
}
template <typename V>
auto VecBase<V>::operator[] (int32_t parIndex) -> scalar_type& {
template <typename I>
auto VecBase<V>::operator[] (I parIndex) -> scalar_type& {
return const_cast<scalar_type&>(const_cast<const VecBase<V>*>(this)->operator[](parIndex));
}
template <typename V>
auto VecBase<V>::operator[] (int64_t parIndex) -> scalar_type& {
return const_cast<scalar_type&>(const_cast<const VecBase<V>*>(this)->operator[](parIndex));
}
template <typename V>
auto VecBase<V>::operator[] (uint64_t parIndex) -> scalar_type& {
return const_cast<scalar_type&>(const_cast<const VecBase<V>*>(this)->operator[](parIndex));
}
template <typename V>
auto VecBase<V>::operator[] (uint32_t parIndex) -> scalar_type& {
return const_cast<scalar_type&>(const_cast<const VecBase<V>*>(this)->operator[](parIndex));
}
template <typename V>
auto VecBase<V>::operator[] (int32_t parIndex) const -> const scalar_type& {
static_assert(sizeof(int32_t) <= sizeof(std::size_t), "Can't support int");
static_assert(static_cast<uint32_t>(std::numeric_limits<int32_t>::max()) <= std::numeric_limits<std::size_t>::max(), "Can't support int32_t");
template <typename I>
auto VecBase<V>::operator[] (I parIndex) const -> const scalar_type& {
static_assert(sizeof(I) <= sizeof(dim_type), "Index type is too large");
static_assert(static_cast<typename std::make_unsigned<I>::type>(std::numeric_limits<I>::max()) <= std::numeric_limits<dim_type>::max(), "This index type can't hold dim_type's max");
assert(parIndex >= 0);
return VecGetter<V>::get_at(const_cast<vector_type&>(m_wrapped), static_cast<std::size_t>(parIndex));
}
template <typename V>
auto VecBase<V>::operator[] (int64_t parIndex) const -> const scalar_type& {
static_assert(sizeof(int64_t) <= sizeof(std::size_t), "Can't support int");
static_assert(static_cast<uint64_t>(std::numeric_limits<int64_t>::max()) <= std::numeric_limits<std::size_t>::max(), "Can't support int64_t");
assert(parIndex >= 0);
return VecGetter<V>::get_at(const_cast<vector_type&>(m_wrapped), static_cast<std::size_t>(parIndex));
}
template <typename V>
auto VecBase<V>::operator[] (uint64_t parIndex) const -> const scalar_type& {
static_assert(std::numeric_limits<uint64_t>::max() <= std::numeric_limits<std::size_t>::max(), "Can't support uint64_t");
return VecGetter<V>::get_at(const_cast<vector_type&>(m_wrapped), static_cast<std::size_t>(parIndex));
}
template <typename V>
auto VecBase<V>::operator[] (uint32_t parIndex) const -> const scalar_type& {
static_assert(std::numeric_limits<uint32_t>::max() <= std::numeric_limits<std::size_t>::max(), "Can't support uint32_t");
return VecGetter<V>::get_at(const_cast<vector_type&>(m_wrapped), static_cast<std::size_t>(parIndex));
return VecGetter<V>::get_at(const_cast<vector_type&>(m_wrapped), static_cast<dim_type>(parIndex));
}
template <typename V>
@ -192,7 +159,7 @@ namespace vwr {
}
template <typename T>
typename VectorWrapperInfo<T>::scalar_type& VecGetter<T, true>::get_at (T& parVec, std::size_t parIndex) {
typename VectorWrapperInfo<T>::scalar_type& VecGetter<T, true>::get_at (T& parVec, dim_type parIndex) {
assert(parIndex < VectorWrapperInfo<T>::dimensions);
typedef T vector_type;
typedef typename VectorWrapperInfo<T>::scalar_type scalar_type;
@ -202,14 +169,14 @@ namespace vwr {
}
template <typename T>
typename VectorWrapperInfo<T>::scalar_type& VecGetter<T, false>::get_at (T& parVec, std::size_t parIndex) {
typename VectorWrapperInfo<T>::scalar_type& VecGetter<T, false>::get_at (T& parVec, dim_type parIndex) {
assert(parIndex < VectorWrapperInfo<T>::dimensions);
return VectorWrapperInfo<T>::get_at(parIndex, parVec);
}
template <typename V1, typename V2, std::size_t D>
template <typename V1, typename V2, dim_type D>
inline Vec<V1>& assign (Vec<V1, D>& parLeft, const Vec<V2, D>& parRight) {
for (std::size_t z = 0; z < D; ++z) {
for (dim_type z = 0; z < D; ++z) {
parLeft[z] = parRight[z];
}
return parLeft;
@ -335,7 +302,7 @@ namespace vwr {
return this_vec[2];
}
template <typename T, std::size_t S>
template <typename T, dim_type S>
template <std::size_t... I>
offsets_array_wrapper<T, S>::offsets_array_wrapper (const bt::index_seq<I...>&) :
offsets({get_offset_enum_from_index<T, I>::value...})