Change hardcoded std::size_t into size_type so it can be customised.

Define VWR_SIZE_TYPE to the type you want to use as the template
index type. It defaults to std::size_t so if you don't do anything
you still get the old behaviour.

Also drop the std::index_range in vector_cast in favour of the custom
bt::number_range, which is already used elsewhere in the code.
This commit is contained in:
King_DuckZ 2016-11-02 03:41:03 +01:00
parent c3844dc246
commit 00470290fe
6 changed files with 88 additions and 66 deletions

View file

@ -0,0 +1,33 @@
/*
* Copyright 2015-2016 Michele "King_DuckZ" Santullo
*
* 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.
*/
#ifndef id85B9A9D5E08C4C97B0E3E69757C6AA54
#define id85B9A9D5E08C4C97B0E3E69757C6AA54
#include <cstddef>
#if defined(VWR_SIZE_TYPE)
# include <cstdint>
#endif
namespace vwr {
#if !defined(VWR_SIZE_TYPE)
typedef std::size_t size_type;
#else
typedef VWR_SIZE_TYPE size_type;
#endif
} //namespace vwr
#endif

View file

@ -17,12 +17,14 @@
#ifndef idE24EF7737A7F4882B2BF254F0A3EEC34
#define idE24EF7737A7F4882B2BF254F0A3EEC34
#include <utility>
#include "vectorwrapper/sequence_bt.hpp"
#include "vectorwrapper/size_type.hpp"
#include "vectorwrapper/vectorwrapper.hpp"
namespace vwr {
namespace implem {
template <typename TO, typename FROM, std::size_t... I>
Vec<TO> vector_cast (const Vec<FROM>& parVec, Vec<TO>*, std::index_sequence<I...>) {
template <typename TO, typename FROM, size_type... I>
Vec<TO> vector_cast (const Vec<FROM>& parVec, Vec<TO>*, bt::number_seq<size_type, I...>) {
static_assert(
static_cast<int>(Vec<TO>::dimensions) == static_cast<int>(Vec<FROM>::dimensions),
"Mismatching dimensions"
@ -37,7 +39,7 @@ namespace vwr {
template <typename TOVec, typename FROM>
TOVec vector_cast (const Vec<FROM>& parVec) {
TOVec* const to = nullptr;
return implem::vector_cast(parVec, to, std::make_index_sequence<Vec<FROM>::dimensions>());
return implem::vector_cast(parVec, to, bt::number_range<size_type, 0, Vec<FROM>::dimensions>());
}
} //namespace vwr

View file

@ -17,18 +17,19 @@
#ifndef id8949C80C36BA42CABC49EA4C1DB54BC7
#define id8949C80C36BA42CABC49EA4C1DB54BC7
#include "vectorwrapper.hpp"
#include "vectorwrapper/vectorwrapper.hpp"
#include "vectorwrapper/size_type.hpp"
#include <type_traits>
#include <cstddef>
namespace vwr {
template <typename V1, typename V2, std::size_t S>
template <typename V1, typename V2, size_type S>
typename std::common_type<typename Vec<V1>::scalar_type, typename Vec<V2>::scalar_type>::type dot ( const Vec<V1, S>& parLeft, const Vec<V2, S>& parRight );
template <typename V1, typename V2, std::size_t S>
template <typename V1, typename V2, size_type S>
inline typename std::common_type<typename Vec<V1>::scalar_type, typename Vec<V2>::scalar_type>::type dot (const Vec<V1, S>& parLeft, const Vec<V2, S>& parRight) {
auto retval = parLeft.x() * parRight.x();
for (std::size_t z = 1; z < S; ++z) {
for (size_type z = 1; z < S; ++z) {
retval += parLeft[z] * parRight[z];
}
return retval;

View file

@ -19,7 +19,7 @@
#include "vectorwrapper/has_method.hpp"
#include "vectorwrapper/sequence_bt.hpp"
#include <cstddef>
#include "vectorwrapper/size_type.hpp"
#include <ciso646>
#include <type_traits>
#include <array>
@ -29,7 +29,7 @@ namespace vwr {
template <typename V>
struct VectorWrapperInfo;
template <typename V, std::size_t S=VectorWrapperInfo<V>::dimensions>
template <typename V, size_type S=VectorWrapperInfo<V>::dimensions>
class Vec;
namespace implem {
@ -40,13 +40,13 @@ namespace vwr {
define_has_enum(cast_ignore_trailing_properties, CastIgnoreTrailingProperties);
#if defined(VWR_WITH_IMPLICIT_CONVERSIONS)
template <typename V1, typename V2, std::size_t D>
template <typename V1, typename V2, size_type D>
Vec<V1>& assign ( Vec<V1, D>& parLeft, const Vec<V2, D>& parRight );
#endif
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, size_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 };
};
@ -60,7 +60,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, size_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) ?
@ -76,7 +76,7 @@ namespace vwr {
template <
typename T,
typename U,
std::size_t S=(
size_type S=(
static_cast<int>(VectorWrapperInfo<T>::dimensions) < static_cast<int>(VectorWrapperInfo<U>::dimensions) ?
static_cast<int>(VectorWrapperInfo<T>::dimensions)
:
@ -150,10 +150,8 @@ namespace vwr {
VecBase ( scalar_type parX, scalar_type parY, Args... parArgs );
~VecBase ( void ) = default;
scalar_type& operator[] ( std::size_t parIndex );
scalar_type& operator[] ( int parIndex );
const scalar_type& operator[] ( std::size_t parIndex ) const;
const scalar_type& operator[] ( int parIndex ) const;
scalar_type& operator[] ( size_type parIndex );
const scalar_type& operator[] ( size_type parIndex ) const;
vector_type& data ( void ) { return m_wrapped; }
const vector_type& data ( void ) const { return m_wrapped; }
@ -169,16 +167,16 @@ namespace vwr {
template <typename V2> VecBase& operator/= ( const VecBase<V2>& parOther );
private:
template <std::size_t... I, typename... Args>
void assign_values (const bt::index_seq<I...>&, Args... parArgs);
template <size_type... I, typename... Args>
void assign_values (const bt::number_seq<size_type, I...>&, Args... parArgs);
vector_type m_wrapped;
};
template <typename T, std::size_t S=VectorWrapperInfo<T>::dimensions>
template <typename T, size_type S=VectorWrapperInfo<T>::dimensions>
struct offsets_array_wrapper {
template <std::size_t... I>
offsets_array_wrapper ( const bt::index_seq<I...>& );
template <size_type... I>
offsets_array_wrapper ( const bt::number_seq<size_type, I...>& );
const std::array<unsigned int, S> offsets;
};
@ -187,7 +185,7 @@ namespace vwr {
struct 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, size_type parIndex );
};
template <typename T>
struct VecGetter<T, false> {
@ -195,14 +193,14 @@ namespace vwr {
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;
typedef T vector_type;
using get_at_func = decltype(&VectorWrapperInfo<T>::get_at)(std::size_t, vector_type&);
using get_at_func = decltype(&VectorWrapperInfo<T>::get_at)(size_type, vector_type&);
using get_at_rettype = typename std::result_of<get_at_func>::type;
static_assert(not std::is_rvalue_reference<get_at_rettype>::value, "rvalue ref return types not implemented");
static_assert(std::is_lvalue_reference<get_at_rettype>::value, "Read-only vectors not implemented");
public:
static get_at_rettype get_at ( T& parVec, std::size_t parIndex );
static get_at_rettype get_at ( T& parVec, size_type parIndex );
};
template <typename V, bool Enabled> struct Vec1Promotion;
@ -258,7 +256,7 @@ namespace vwr {
lower_vector_type yz ( void ) const;
};
template <typename V, std::size_t D>
template <typename V, size_type D>
struct VecAccessors;
//Workaround for visual studio - VecAccessors<V, 3> should inherit from
@ -295,7 +293,7 @@ namespace vwr {
};
} //namespace implem
template <typename V, std::size_t S>
template <typename V, size_type S>
class Vec : public implem::VecBase<V> {
public:
enum {

View file

@ -23,7 +23,7 @@ namespace vwr {
template <typename V>
template <typename T>
VecBase<V>::VecBase (const T& parInit, typename std::enable_if<std::is_same<T, scalar_type>::value and not std::is_same<scalar_type, vector_type>::value, bool>::type) {
for (std::size_t z = 0; z < VectorWrapperInfo<V>::dimensions; ++z) {
for (size_type z = 0; z < VectorWrapperInfo<V>::dimensions; ++z) {
VecGetter<V>::get_at(m_wrapped, z) = parInit;
}
}
@ -41,12 +41,12 @@ namespace vwr {
VecGetter<V>::get_at(m_wrapped, 0) = parX;
VecGetter<V>::get_at(m_wrapped, 1) = parY;
assign_values(bt::index_range<2, dimensions>(), std::forward<Args>(parArgs)...);
assign_values(bt::number_range<size_type, 2, dimensions>(), std::forward<Args>(parArgs)...);
}
template <typename V>
template <std::size_t... I, typename... Args>
void VecBase<V>::assign_values (const bt::index_seq<I...>&, Args... parArgs) {
template <size_type... I, typename... Args>
void VecBase<V>::assign_values (const bt::number_seq<size_type, I...>&, Args... parArgs) {
static_assert(sizeof...(I) == sizeof...(Args), "Argument count and indices count mismatch");
std::initializer_list<scalar_type> t {
@ -56,27 +56,15 @@ namespace vwr {
}
template <typename V>
auto VecBase<V>::operator[] (std::size_t parIndex) -> scalar_type& {
auto VecBase<V>::operator[] (size_type parIndex) -> scalar_type& {
return VecGetter<V>::get_at(m_wrapped, parIndex);
}
template <typename V>
auto VecBase<V>::operator[] (int parIndex) -> scalar_type& {
assert(parIndex >= 0);
return VecGetter<V>::get_at(m_wrapped, static_cast<std::size_t>(parIndex));
}
template <typename V>
auto VecBase<V>::operator[] (std::size_t parIndex) const -> const scalar_type& {
auto VecBase<V>::operator[] (size_type parIndex) const -> const scalar_type& {
return VecGetter<V>::get_at(const_cast<vector_type&>(m_wrapped), parIndex);
}
template <typename V>
auto VecBase<V>::operator[] (int parIndex) const -> const scalar_type& {
assert(parIndex >= 0);
return VecGetter<V>::get_at(const_cast<vector_type&>(m_wrapped), static_cast<std::size_t>(parIndex));
}
template <typename V>
template <typename V2>
const typename std::enable_if<is_vec<V2>::value, V2>::type& VecBase<V>::cast() const {
@ -107,7 +95,7 @@ namespace vwr {
template <typename V2>
VecBase<V>& VecBase<V>::operator+= (const VecBase<V2>& parOther) {
static_assert(static_cast<int>(VectorWrapperInfo<V>::dimensions) == static_cast<int>(VectorWrapperInfo<V2>::dimensions), "Dimensions mismatch");
for (int z = 0; z < VectorWrapperInfo<V>::dimensions; ++z) {
for (size_type z = 0; z < VectorWrapperInfo<V>::dimensions; ++z) {
(*this)[z] += parOther[z];
}
return *this;
@ -116,7 +104,7 @@ namespace vwr {
template <typename V2>
VecBase<V>& VecBase<V>::operator-= (const VecBase<V2>& parOther) {
static_assert(static_cast<int>(VectorWrapperInfo<V>::dimensions) == static_cast<int>(VectorWrapperInfo<V2>::dimensions), "Dimensions mismatch");
for (int z = 0; z < VectorWrapperInfo<V>::dimensions; ++z) {
for (size_type z = 0; z < VectorWrapperInfo<V>::dimensions; ++z) {
(*this)[z] -= parOther[z];
}
return *this;
@ -125,7 +113,7 @@ namespace vwr {
template <typename V2>
VecBase<V>& VecBase<V>::operator*= (const VecBase<V2>& parOther) {
static_assert(static_cast<int>(VectorWrapperInfo<V>::dimensions) == static_cast<int>(VectorWrapperInfo<V2>::dimensions), "Dimensions mismatch");
for (int z = 0; z < VectorWrapperInfo<V>::dimensions; ++z) {
for (size_type z = 0; z < VectorWrapperInfo<V>::dimensions; ++z) {
(*this)[z] *= parOther[z];
}
return *this;
@ -141,24 +129,24 @@ 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, size_type parIndex) {
assert(parIndex < VectorWrapperInfo<T>::dimensions);
typedef T vector_type;
typedef typename VectorWrapperInfo<T>::scalar_type scalar_type;
static_assert(std::is_standard_layout<vector_type>::value, "Can't use this function with this vector_type");
const offsets_array_wrapper<T> oaw((bt::index_range<0, VectorWrapperInfo<T>::dimensions>()));
const offsets_array_wrapper<T> oaw((bt::number_range<size_type, 0, VectorWrapperInfo<T>::dimensions>()));
return *reinterpret_cast<scalar_type*>(reinterpret_cast<char*>(&parVec) + oaw.offsets[parIndex]);
}
template <typename T>
auto VecGetter<T, false>::get_at (T& parVec, std::size_t parIndex) -> get_at_rettype {
auto VecGetter<T, false>::get_at (T& parVec, size_type parIndex) -> get_at_rettype {
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, size_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 (size_type z = 0; z < D; ++z) {
parLeft[z] = parRight[z];
}
return parLeft;
@ -284,9 +272,9 @@ namespace vwr {
return this_vec[2];
}
template <typename T, std::size_t S>
template <std::size_t... I>
offsets_array_wrapper<T, S>::offsets_array_wrapper (const bt::index_seq<I...>&) :
template <typename T, size_type S>
template <size_type... I>
offsets_array_wrapper<T, S>::offsets_array_wrapper (const bt::number_seq<size_type, I...>&) :
offsets({get_offset_enum_from_index<T, I>::value...})
{
static_assert(sizeof...(I) == S, "Bug?");
@ -309,7 +297,7 @@ namespace vwr {
inline bool operator== (const Vec<V1>& parLeft, const Vec<V2>& parRight) {
static_assert(static_cast<int>(VectorWrapperInfo<V1>::dimensions) == static_cast<int>(VectorWrapperInfo<V2>::dimensions), "Dimensions mismatch");
bool retval = true;
for (int z = 0; z < VectorWrapperInfo<V1>::dimensions; ++z) {
for (size_type z = 0; z < VectorWrapperInfo<V1>::dimensions; ++z) {
retval &= (parLeft[z] == parRight[z]);
}
return retval;
@ -318,7 +306,7 @@ namespace vwr {
inline bool operator< (const Vec<V1>& parLeft, const Vec<V2>& parRight) {
static_assert(static_cast<int>(VectorWrapperInfo<V1>::dimensions) == static_cast<int>(VectorWrapperInfo<V2>::dimensions), "Dimensions mismatch");
bool retval = true;
for (int z = 0; z < VectorWrapperInfo<V1>::dimensions; ++z) {
for (size_type z = 0; z < VectorWrapperInfo<V1>::dimensions; ++z) {
retval &= (parLeft[z] < parRight[z]);
}
return retval;
@ -327,7 +315,7 @@ namespace vwr {
template <typename V>
inline bool operator== (const Vec<V>& parLeft, const typename VectorWrapperInfo<V>::scalar_type& parRight) {
bool retval = true;
for (int z = 0; z < VectorWrapperInfo<V>::dimensions; ++z) {
for (size_type z = 0; z < VectorWrapperInfo<V>::dimensions; ++z) {
retval &= (parLeft[z] == parRight);
}
return retval;
@ -335,7 +323,7 @@ namespace vwr {
template <typename V>
inline bool operator< ( const Vec<V>& parLeft, const typename VectorWrapperInfo<V>::scalar_type& parRight) {
bool retval = true;
for (int z = 0; z < VectorWrapperInfo<V>::dimensions; ++z) {
for (size_type z = 0; z < VectorWrapperInfo<V>::dimensions; ++z) {
retval &= (parLeft[z] < parRight);
}
return retval;
@ -366,7 +354,7 @@ namespace vwr {
static_assert(static_cast<int>(VectorWrapperInfo<V1>::dimensions) == static_cast<int>(VectorWrapperInfo<V2>::dimensions), "Dimensions mismatch");
Vec<typename std::common_type<V1, V2>::type> retval;
for (int z = 0; z < VectorWrapperInfo<V1>::dimensions; ++z) {
for (size_type z = 0; z < VectorWrapperInfo<V1>::dimensions; ++z) {
#if defined(VWR_STATIC_CAST_RESULTS)
retval[z] = static_cast<scalar_type>(parLeft[z] + parRight[z]);
#else
@ -383,7 +371,7 @@ namespace vwr {
static_assert(static_cast<int>(VectorWrapperInfo<V1>::dimensions) == static_cast<int>(VectorWrapperInfo<V2>::dimensions), "Dimensions mismatch");
Vec<typename std::common_type<V1, V2>::type> retval;
for (int z = 0; z < VectorWrapperInfo<V1>::dimensions; ++z) {
for (size_type z = 0; z < VectorWrapperInfo<V1>::dimensions; ++z) {
#if defined(VWR_STATIC_CAST_RESULTS)
retval[z] = static_cast<scalar_type>(parLeft[z] - parRight[z]);
#else
@ -400,7 +388,7 @@ namespace vwr {
static_assert(static_cast<int>(VectorWrapperInfo<V1>::dimensions) == static_cast<int>(VectorWrapperInfo<V2>::dimensions), "Dimensions mismatch");
Vec<typename std::common_type<V1, V2>::type> retval;
for (int z = 0; z < VectorWrapperInfo<V1>::dimensions; ++z) {
for (size_type z = 0; z < VectorWrapperInfo<V1>::dimensions; ++z) {
#if defined(VWR_STATIC_CAST_RESULTS)
retval[z] = static_cast<scalar_type>(parLeft[z] * parRight[z]);
#else
@ -417,7 +405,7 @@ namespace vwr {
static_assert(static_cast<int>(VectorWrapperInfo<V1>::dimensions) == static_cast<int>(VectorWrapperInfo<V2>::dimensions), "Dimensions mismatch");
Vec<typename std::common_type<V1, V2>::type> retval;
for (int z = 0; z < VectorWrapperInfo<V1>::dimensions; ++z) {
for (size_type z = 0; z < VectorWrapperInfo<V1>::dimensions; ++z) {
#if defined(VWR_STATIC_CAST_RESULTS)
retval[z] = static_cast<scalar_type>(parLeft[z] / parRight[z]);
#else

View file

@ -62,7 +62,7 @@ namespace vwr {
typedef float scalar_type;
typedef SimpleVector2 higher_vector_type;
static scalar_type& get_at (std::size_t, vector_type& parVector) {
static scalar_type& get_at (size_type, vector_type& parVector) {
return parVector;
}
};