mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-06-04 18:54:00 +08:00
Rollback or PR-746 and partial rollback of 668ab3fc47
. std::array is still not supported in CUDA device code on Windows.
This commit is contained in:
parent
0c9745903a
commit
ee404667e2
@ -369,7 +369,7 @@ template<typename T, int _Options> class DenseStorage<T, Dynamic, Dynamic, Dynam
|
|||||||
, m_cols(other.m_cols)
|
, m_cols(other.m_cols)
|
||||||
{
|
{
|
||||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = m_rows*m_cols)
|
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = m_rows*m_cols)
|
||||||
std::copy(other.m_data, other.m_data+other.m_rows*other.m_cols, m_data);
|
internal::smart_copy(other.m_data, other.m_data+other.m_rows*other.m_cols, m_data);
|
||||||
}
|
}
|
||||||
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
|
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
|
||||||
{
|
{
|
||||||
@ -452,7 +452,7 @@ template<typename T, int _Rows, int _Options> class DenseStorage<T, Dynamic, _Ro
|
|||||||
, m_cols(other.m_cols)
|
, m_cols(other.m_cols)
|
||||||
{
|
{
|
||||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = m_cols*_Rows)
|
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = m_cols*_Rows)
|
||||||
std::copy(other.m_data, other.m_data+_Rows*m_cols, m_data);
|
internal::smart_copy(other.m_data, other.m_data+_Rows*m_cols, m_data);
|
||||||
}
|
}
|
||||||
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
|
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
|
||||||
{
|
{
|
||||||
@ -528,7 +528,7 @@ template<typename T, int _Cols, int _Options> class DenseStorage<T, Dynamic, Dyn
|
|||||||
, m_rows(other.m_rows)
|
, m_rows(other.m_rows)
|
||||||
{
|
{
|
||||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = m_rows*_Cols)
|
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = m_rows*_Cols)
|
||||||
std::copy(other.m_data, other.m_data+other.m_rows*_Cols, m_data);
|
internal::smart_copy(other.m_data, other.m_data+other.m_rows*_Cols, m_data);
|
||||||
}
|
}
|
||||||
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
|
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
|
||||||
{
|
{
|
||||||
|
@ -507,6 +507,31 @@ inline Index first_multiple(Index size, Index base)
|
|||||||
return ((size+base-1)/base)*base;
|
return ((size+base-1)/base)*base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// std::copy is much slower than memcpy, so let's introduce a smart_copy which
|
||||||
|
// use memcpy on trivial types, i.e., on types that does not require an initialization ctor.
|
||||||
|
template<typename T, bool UseMemcpy> struct smart_copy_helper;
|
||||||
|
|
||||||
|
template<typename T> EIGEN_DEVICE_FUNC void smart_copy(const T* start, const T* end, T* target)
|
||||||
|
{
|
||||||
|
smart_copy_helper<T,!NumTraits<T>::RequireInitialization>::run(start, end, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T> struct smart_copy_helper<T,true> {
|
||||||
|
EIGEN_DEVICE_FUNC static inline void run(const T* start, const T* end, T* target)
|
||||||
|
{
|
||||||
|
IntPtr size = IntPtr(end)-IntPtr(start);
|
||||||
|
if(size==0) return;
|
||||||
|
eigen_internal_assert(start!=0 && end!=0 && target!=0);
|
||||||
|
EIGEN_USING_STD(memcpy)
|
||||||
|
memcpy(target, start, size);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T> struct smart_copy_helper<T,false> {
|
||||||
|
EIGEN_DEVICE_FUNC static inline void run(const T* start, const T* end, T* target)
|
||||||
|
{ std::copy(start, end, target); }
|
||||||
|
};
|
||||||
|
|
||||||
// intelligent memmove. falls back to std::memmove for POD types, uses std::copy otherwise.
|
// intelligent memmove. falls back to std::memmove for POD types, uses std::copy otherwise.
|
||||||
template<typename T, bool UseMemmove> struct smart_memmove_helper;
|
template<typename T, bool UseMemmove> struct smart_memmove_helper;
|
||||||
|
|
||||||
|
@ -53,8 +53,8 @@ class CompressedStorage
|
|||||||
resize(other.size());
|
resize(other.size());
|
||||||
if(other.size()>0)
|
if(other.size()>0)
|
||||||
{
|
{
|
||||||
std::copy(other.m_values, other.m_values + m_size, m_values);
|
internal::smart_copy(other.m_values, other.m_values + m_size, m_values);
|
||||||
std::copy(other.m_indices, other.m_indices + m_size, m_indices);
|
internal::smart_copy(other.m_indices, other.m_indices + m_size, m_indices);
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -183,14 +183,14 @@ class CompressedStorage
|
|||||||
internal::scoped_array<StorageIndex> newIndices(m_allocatedSize);
|
internal::scoped_array<StorageIndex> newIndices(m_allocatedSize);
|
||||||
|
|
||||||
// copy first chunk
|
// copy first chunk
|
||||||
std::copy(m_values, m_values +id, newValues.ptr());
|
internal::smart_copy(m_values, m_values +id, newValues.ptr());
|
||||||
std::copy(m_indices, m_indices+id, newIndices.ptr());
|
internal::smart_copy(m_indices, m_indices+id, newIndices.ptr());
|
||||||
|
|
||||||
// copy the rest
|
// copy the rest
|
||||||
if(m_size>id)
|
if(m_size>id)
|
||||||
{
|
{
|
||||||
std::copy(m_values +id, m_values +m_size, newValues.ptr() +id+1);
|
internal::smart_copy(m_values +id, m_values +m_size, newValues.ptr() +id+1);
|
||||||
std::copy(m_indices+id, m_indices+m_size, newIndices.ptr()+id+1);
|
internal::smart_copy(m_indices+id, m_indices+m_size, newIndices.ptr()+id+1);
|
||||||
}
|
}
|
||||||
std::swap(m_values,newValues.ptr());
|
std::swap(m_values,newValues.ptr());
|
||||||
std::swap(m_indices,newIndices.ptr());
|
std::swap(m_indices,newIndices.ptr());
|
||||||
@ -218,8 +218,8 @@ class CompressedStorage
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::copy(m_values+from, m_values+from+chunkSize, m_values+to);
|
internal::smart_copy(m_values+from, m_values+from+chunkSize, m_values+to);
|
||||||
std::copy(m_indices+from, m_indices+from+chunkSize, m_indices+to);
|
internal::smart_copy(m_indices+from, m_indices+from+chunkSize, m_indices+to);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -251,8 +251,8 @@ class CompressedStorage
|
|||||||
internal::scoped_array<StorageIndex> newIndices(size);
|
internal::scoped_array<StorageIndex> newIndices(size);
|
||||||
Index copySize = (std::min)(size, m_size);
|
Index copySize = (std::min)(size, m_size);
|
||||||
if (copySize>0) {
|
if (copySize>0) {
|
||||||
std::copy(m_values, m_values+copySize, newValues.ptr());
|
internal::smart_copy(m_values, m_values+copySize, newValues.ptr());
|
||||||
std::copy(m_indices, m_indices+copySize, newIndices.ptr());
|
internal::smart_copy(m_indices, m_indices+copySize, newIndices.ptr());
|
||||||
}
|
}
|
||||||
std::swap(m_values,newValues.ptr());
|
std::swap(m_values,newValues.ptr());
|
||||||
std::swap(m_indices,newIndices.ptr());
|
std::swap(m_indices,newIndices.ptr());
|
||||||
|
@ -147,14 +147,14 @@ public:
|
|||||||
// realloc manually to reduce copies
|
// realloc manually to reduce copies
|
||||||
typename SparseMatrixType::Storage newdata(m_matrix.data().allocatedSize() - block_size + nnz);
|
typename SparseMatrixType::Storage newdata(m_matrix.data().allocatedSize() - block_size + nnz);
|
||||||
|
|
||||||
std::copy(m_matrix.valuePtr(), m_matrix.valuePtr() + start, newdata.valuePtr());
|
internal::smart_copy(m_matrix.valuePtr(), m_matrix.valuePtr() + start, newdata.valuePtr());
|
||||||
std::copy(m_matrix.innerIndexPtr(), m_matrix.innerIndexPtr() + start, newdata.indexPtr());
|
internal::smart_copy(m_matrix.innerIndexPtr(), m_matrix.innerIndexPtr() + start, newdata.indexPtr());
|
||||||
|
|
||||||
std::copy(tmp.valuePtr() + tmp_start, tmp.valuePtr() + tmp_start + nnz, newdata.valuePtr() + start);
|
internal::smart_copy(tmp.valuePtr() + tmp_start, tmp.valuePtr() + tmp_start + nnz, newdata.valuePtr() + start);
|
||||||
std::copy(tmp.innerIndexPtr() + tmp_start, tmp.innerIndexPtr() + tmp_start + nnz, newdata.indexPtr() + start);
|
internal::smart_copy(tmp.innerIndexPtr() + tmp_start, tmp.innerIndexPtr() + tmp_start + nnz, newdata.indexPtr() + start);
|
||||||
|
|
||||||
std::copy(matrix.valuePtr()+end, matrix.valuePtr()+end + tail_size, newdata.valuePtr()+start+nnz);
|
internal::smart_copy(matrix.valuePtr()+end, matrix.valuePtr()+end + tail_size, newdata.valuePtr()+start+nnz);
|
||||||
std::copy(matrix.innerIndexPtr()+end, matrix.innerIndexPtr()+end + tail_size, newdata.indexPtr()+start+nnz);
|
internal::smart_copy(matrix.innerIndexPtr()+end, matrix.innerIndexPtr()+end + tail_size, newdata.indexPtr()+start+nnz);
|
||||||
|
|
||||||
newdata.resize(m_matrix.outerIndexPtr()[m_matrix.outerSize()] - block_size + nnz);
|
newdata.resize(m_matrix.outerIndexPtr()[m_matrix.outerSize()] - block_size + nnz);
|
||||||
|
|
||||||
@ -175,8 +175,8 @@ public:
|
|||||||
update_trailing_pointers = true;
|
update_trailing_pointers = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::copy(tmp.valuePtr() + tmp_start, tmp.valuePtr() + tmp_start + nnz, matrix.valuePtr() + start);
|
internal::smart_copy(tmp.valuePtr() + tmp_start, tmp.valuePtr() + tmp_start + nnz, matrix.valuePtr() + start);
|
||||||
std::copy(tmp.innerIndexPtr() + tmp_start, tmp.innerIndexPtr() + tmp_start + nnz, matrix.innerIndexPtr() + start);
|
internal::smart_copy(tmp.innerIndexPtr() + tmp_start, tmp.innerIndexPtr() + tmp_start + nnz, matrix.innerIndexPtr() + start);
|
||||||
}
|
}
|
||||||
|
|
||||||
// update outer index pointers and innerNonZeros
|
// update outer index pointers and innerNonZeros
|
||||||
|
@ -767,7 +767,7 @@ class SparseMatrix
|
|||||||
initAssignment(other);
|
initAssignment(other);
|
||||||
if(other.isCompressed())
|
if(other.isCompressed())
|
||||||
{
|
{
|
||||||
std::copy(other.m_outerIndex, other.m_outerIndex + m_outerSize + 1, m_outerIndex);
|
internal::smart_copy(other.m_outerIndex, other.m_outerIndex + m_outerSize + 1, m_outerIndex);
|
||||||
m_data = other.m_data;
|
m_data = other.m_data;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -982,8 +982,8 @@ protected:
|
|||||||
{
|
{
|
||||||
Index i = newEntries[k].i;
|
Index i = newEntries[k].i;
|
||||||
Index p = newEntries[k].p;
|
Index p = newEntries[k].p;
|
||||||
std::copy(m_data.valuePtr()+prev_p, m_data.valuePtr()+p, newData.valuePtr()+prev_p+k);
|
internal::smart_copy(m_data.valuePtr()+prev_p, m_data.valuePtr()+p, newData.valuePtr()+prev_p+k);
|
||||||
std::copy(m_data.indexPtr()+prev_p, m_data.indexPtr()+p, newData.indexPtr()+prev_p+k);
|
internal::smart_copy(m_data.indexPtr()+prev_p, m_data.indexPtr()+p, newData.indexPtr()+prev_p+k);
|
||||||
for(Index j=prev_i;j<i;++j)
|
for(Index j=prev_i;j<i;++j)
|
||||||
m_outerIndex[j+1] += k;
|
m_outerIndex[j+1] += k;
|
||||||
if(!isComp)
|
if(!isComp)
|
||||||
@ -995,8 +995,8 @@ protected:
|
|||||||
assignFunc.assignCoeff(newData.value(p+k), diaEval.coeff(i));
|
assignFunc.assignCoeff(newData.value(p+k), diaEval.coeff(i));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::copy(m_data.valuePtr()+prev_p, m_data.valuePtr()+m_data.size(), newData.valuePtr()+prev_p+n_entries);
|
internal::smart_copy(m_data.valuePtr()+prev_p, m_data.valuePtr()+m_data.size(), newData.valuePtr()+prev_p+n_entries);
|
||||||
std::copy(m_data.indexPtr()+prev_p, m_data.indexPtr()+m_data.size(), newData.indexPtr()+prev_p+n_entries);
|
internal::smart_copy(m_data.indexPtr()+prev_p, m_data.indexPtr()+m_data.size(), newData.indexPtr()+prev_p+n_entries);
|
||||||
for(Index j=prev_i+1;j<=m_outerSize;++j)
|
for(Index j=prev_i+1;j<=m_outerSize;++j)
|
||||||
m_outerIndex[j] += n_entries;
|
m_outerIndex[j] += n_entries;
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ class TensorStorage<T, DSizes<IndexType, NumIndices_>, Options_>
|
|||||||
: m_data(internal::conditional_aligned_new_auto<T,(Options_&DontAlign)==0>(internal::array_prod(other.m_dimensions)))
|
: m_data(internal::conditional_aligned_new_auto<T,(Options_&DontAlign)==0>(internal::array_prod(other.m_dimensions)))
|
||||||
, m_dimensions(other.m_dimensions)
|
, m_dimensions(other.m_dimensions)
|
||||||
{
|
{
|
||||||
std::copy(other.m_data, other.m_data+internal::array_prod(other.m_dimensions), m_data);
|
internal::smart_copy(other.m_data, other.m_data+internal::array_prod(other.m_dimensions), m_data);
|
||||||
}
|
}
|
||||||
EIGEN_DEVICE_FUNC Self& operator=(const Self& other)
|
EIGEN_DEVICE_FUNC Self& operator=(const Self& other)
|
||||||
{
|
{
|
||||||
|
@ -11,100 +11,13 @@
|
|||||||
#define EIGEN_CXX11META_H
|
#define EIGEN_CXX11META_H
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <array>
|
#include "EmulateArray.h"
|
||||||
|
|
||||||
#include "CXX11Workarounds.h"
|
#include "CXX11Workarounds.h"
|
||||||
|
|
||||||
namespace Eigen {
|
namespace Eigen {
|
||||||
|
|
||||||
// Workaround for constructors used by legacy code calling Eigen::array.
|
|
||||||
template <typename T, size_t N>
|
|
||||||
class array : public std::array<T, N> {
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef std::array<T, N> Base;
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
array() : Base() {}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
array(const T& v) : Base{{v}} {
|
|
||||||
EIGEN_STATIC_ASSERT(N == 1, YOU_MADE_A_PROGRAMMING_MISTAKE);
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
array(const T& v1, const T& v2) : Base{{v1, v2}} {
|
|
||||||
EIGEN_STATIC_ASSERT(N == 2, YOU_MADE_A_PROGRAMMING_MISTAKE);
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
array(const T& v1, const T& v2, const T& v3) : Base{{v1, v2, v3}} {
|
|
||||||
EIGEN_STATIC_ASSERT(N == 3, YOU_MADE_A_PROGRAMMING_MISTAKE);
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
array(const T& v1, const T& v2, const T& v3, const T& v4)
|
|
||||||
: Base{{v1, v2, v3, v4}} {
|
|
||||||
EIGEN_STATIC_ASSERT(N == 4, YOU_MADE_A_PROGRAMMING_MISTAKE);
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
array(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5)
|
|
||||||
: Base{{v1, v2, v3, v4, v5}} {
|
|
||||||
EIGEN_STATIC_ASSERT(N == 5, YOU_MADE_A_PROGRAMMING_MISTAKE);
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
array(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5,
|
|
||||||
const T& v6) : Base{{v1, v2, v3, v4, v5, v6}} {
|
|
||||||
EIGEN_STATIC_ASSERT(N == 6, YOU_MADE_A_PROGRAMMING_MISTAKE);
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
array(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5,
|
|
||||||
const T& v6, const T& v7)
|
|
||||||
: Base{{v1, v2, v3, v4, v5, v6, v7}} {
|
|
||||||
EIGEN_STATIC_ASSERT(N == 7, YOU_MADE_A_PROGRAMMING_MISTAKE);
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
array(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5,
|
|
||||||
const T& v6, const T& v7, const T& v8)
|
|
||||||
: Base{{v1, v2, v3, v4, v5, v6, v7, v8}} {
|
|
||||||
EIGEN_STATIC_ASSERT(N == 8, YOU_MADE_A_PROGRAMMING_MISTAKE);
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
array(std::initializer_list<T> l) {
|
|
||||||
eigen_assert(l.size() == N);
|
|
||||||
std::copy(l.begin(), l.end(), &this->front());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
template<typename T, std::size_t N> struct array_size<const array<T,N> > {
|
|
||||||
enum { value = N };
|
|
||||||
};
|
|
||||||
template<typename T, std::size_t N> struct array_size<array<T,N> > {
|
|
||||||
enum { value = N };
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* std::get is only constexpr in C++14, not yet in C++11
|
|
||||||
* - libstdc++ from version 4.7 onwards has it nevertheless,
|
|
||||||
* so use that
|
|
||||||
* - libstdc++ older versions: use _M_instance directly
|
|
||||||
* - libc++ all versions so far: use __elems_ directly
|
|
||||||
* - all other libs: use std::get to be portable, but
|
|
||||||
* this may not be constexpr
|
|
||||||
*/
|
|
||||||
#if defined(__GLIBCXX__) && __GLIBCXX__ < 20120322
|
|
||||||
#define STD_GET_ARR_HACK a._M_instance[I_]
|
|
||||||
#elif defined(_LIBCPP_VERSION)
|
|
||||||
#define STD_GET_ARR_HACK a.__elems_[I_]
|
|
||||||
#else
|
|
||||||
#define STD_GET_ARR_HACK std::template get<I_, T, N>(a)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<std::size_t I_, class T, std::size_t N> constexpr inline T& array_get(std::array<T,N>& a) { return (T&) STD_GET_ARR_HACK; }
|
|
||||||
template<std::size_t I_, class T, std::size_t N> constexpr inline T&& array_get(std::array<T,N>&& a) { return (T&&) STD_GET_ARR_HACK; }
|
|
||||||
template<std::size_t I_, class T, std::size_t N> constexpr inline T const& array_get(std::array<T,N> const& a) { return (T const&) STD_GET_ARR_HACK; }
|
|
||||||
|
|
||||||
#undef STD_GET_ARR_HACK
|
|
||||||
|
|
||||||
/** \internal
|
/** \internal
|
||||||
* \file CXX11/util/CXX11Meta.h
|
* \file CXX11/util/CXX11Meta.h
|
||||||
|
261
unsupported/Eigen/CXX11/src/util/EmulateArray.h
Normal file
261
unsupported/Eigen/CXX11/src/util/EmulateArray.h
Normal file
@ -0,0 +1,261 @@
|
|||||||
|
// This file is part of Eigen, a lightweight C++ template library
|
||||||
|
// for linear algebra.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2014 Benoit Steiner <benoit.steiner.goog@gmail.com>
|
||||||
|
//
|
||||||
|
// This Source Code Form is subject to the terms of the Mozilla
|
||||||
|
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||||
|
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
#ifndef EIGEN_EMULATE_ARRAY_H
|
||||||
|
#define EIGEN_EMULATE_ARRAY_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// The array class is only available starting with cxx11. Emulate our own here
|
||||||
|
// if needed. Beware, msvc still doesn't advertise itself as a c++11 compiler!
|
||||||
|
// Moreover, CUDA doesn't support the STL containers, so we use our own instead.
|
||||||
|
#if (__cplusplus <= 199711L && EIGEN_COMP_MSVC < 1900) || defined(EIGEN_GPUCC) || defined(EIGEN_AVOID_STL_ARRAY)
|
||||||
|
|
||||||
|
namespace Eigen {
|
||||||
|
template <typename T, size_t n> class array {
|
||||||
|
public:
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
EIGEN_STRONG_INLINE T& operator[] (size_t index) { eigen_internal_assert(index < size()); return values[index]; }
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
EIGEN_STRONG_INLINE const T& operator[] (size_t index) const { eigen_internal_assert(index < size()); return values[index]; }
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
EIGEN_STRONG_INLINE T& at(size_t index) { eigen_assert(index < size()); return values[index]; }
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
EIGEN_STRONG_INLINE const T& at(size_t index) const { eigen_assert(index < size()); return values[index]; }
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
EIGEN_STRONG_INLINE T& front() { return values[0]; }
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
EIGEN_STRONG_INLINE const T& front() const { return values[0]; }
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
EIGEN_STRONG_INLINE T& back() { return values[n-1]; }
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
EIGEN_STRONG_INLINE const T& back() const { return values[n-1]; }
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
|
||||||
|
static std::size_t size() { return n; }
|
||||||
|
|
||||||
|
T values[n];
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
EIGEN_STRONG_INLINE array() { }
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
EIGEN_STRONG_INLINE array(const T& v) {
|
||||||
|
EIGEN_STATIC_ASSERT(n==1, YOU_MADE_A_PROGRAMMING_MISTAKE)
|
||||||
|
values[0] = v;
|
||||||
|
}
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
EIGEN_STRONG_INLINE array(const T& v1, const T& v2) {
|
||||||
|
EIGEN_STATIC_ASSERT(n==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
|
||||||
|
values[0] = v1;
|
||||||
|
values[1] = v2;
|
||||||
|
}
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3) {
|
||||||
|
EIGEN_STATIC_ASSERT(n==3, YOU_MADE_A_PROGRAMMING_MISTAKE)
|
||||||
|
values[0] = v1;
|
||||||
|
values[1] = v2;
|
||||||
|
values[2] = v3;
|
||||||
|
}
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3,
|
||||||
|
const T& v4) {
|
||||||
|
EIGEN_STATIC_ASSERT(n==4, YOU_MADE_A_PROGRAMMING_MISTAKE)
|
||||||
|
values[0] = v1;
|
||||||
|
values[1] = v2;
|
||||||
|
values[2] = v3;
|
||||||
|
values[3] = v4;
|
||||||
|
}
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4,
|
||||||
|
const T& v5) {
|
||||||
|
EIGEN_STATIC_ASSERT(n==5, YOU_MADE_A_PROGRAMMING_MISTAKE)
|
||||||
|
values[0] = v1;
|
||||||
|
values[1] = v2;
|
||||||
|
values[2] = v3;
|
||||||
|
values[3] = v4;
|
||||||
|
values[4] = v5;
|
||||||
|
}
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4,
|
||||||
|
const T& v5, const T& v6) {
|
||||||
|
EIGEN_STATIC_ASSERT(n==6, YOU_MADE_A_PROGRAMMING_MISTAKE)
|
||||||
|
values[0] = v1;
|
||||||
|
values[1] = v2;
|
||||||
|
values[2] = v3;
|
||||||
|
values[3] = v4;
|
||||||
|
values[4] = v5;
|
||||||
|
values[5] = v6;
|
||||||
|
}
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4,
|
||||||
|
const T& v5, const T& v6, const T& v7) {
|
||||||
|
EIGEN_STATIC_ASSERT(n==7, YOU_MADE_A_PROGRAMMING_MISTAKE)
|
||||||
|
values[0] = v1;
|
||||||
|
values[1] = v2;
|
||||||
|
values[2] = v3;
|
||||||
|
values[3] = v4;
|
||||||
|
values[4] = v5;
|
||||||
|
values[5] = v6;
|
||||||
|
values[6] = v7;
|
||||||
|
}
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
EIGEN_STRONG_INLINE array(
|
||||||
|
const T& v1, const T& v2, const T& v3, const T& v4,
|
||||||
|
const T& v5, const T& v6, const T& v7, const T& v8) {
|
||||||
|
EIGEN_STATIC_ASSERT(n==8, YOU_MADE_A_PROGRAMMING_MISTAKE)
|
||||||
|
values[0] = v1;
|
||||||
|
values[1] = v2;
|
||||||
|
values[2] = v3;
|
||||||
|
values[3] = v4;
|
||||||
|
values[4] = v5;
|
||||||
|
values[5] = v6;
|
||||||
|
values[6] = v7;
|
||||||
|
values[7] = v8;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if EIGEN_HAS_VARIADIC_TEMPLATES
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
EIGEN_STRONG_INLINE array(std::initializer_list<T> l) {
|
||||||
|
eigen_assert(l.size() == n);
|
||||||
|
internal::smart_copy(l.begin(), l.end(), values);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Specialize array for zero size
|
||||||
|
template <typename T> class array<T, 0> {
|
||||||
|
public:
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
EIGEN_STRONG_INLINE T& operator[] (size_t) {
|
||||||
|
eigen_assert(false && "Can't index a zero size array");
|
||||||
|
return dummy;
|
||||||
|
}
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
EIGEN_STRONG_INLINE const T& operator[] (size_t) const {
|
||||||
|
eigen_assert(false && "Can't index a zero size array");
|
||||||
|
return dummy;
|
||||||
|
}
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
EIGEN_STRONG_INLINE T& front() {
|
||||||
|
eigen_assert(false && "Can't index a zero size array");
|
||||||
|
return dummy;
|
||||||
|
}
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
EIGEN_STRONG_INLINE const T& front() const {
|
||||||
|
eigen_assert(false && "Can't index a zero size array");
|
||||||
|
return dummy;
|
||||||
|
}
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
EIGEN_STRONG_INLINE T& back() {
|
||||||
|
eigen_assert(false && "Can't index a zero size array");
|
||||||
|
return dummy;
|
||||||
|
}
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
EIGEN_STRONG_INLINE const T& back() const {
|
||||||
|
eigen_assert(false && "Can't index a zero size array");
|
||||||
|
return dummy;
|
||||||
|
}
|
||||||
|
|
||||||
|
static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE std::size_t size() { return 0; }
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
EIGEN_STRONG_INLINE array() : dummy() { }
|
||||||
|
|
||||||
|
#if EIGEN_HAS_VARIADIC_TEMPLATES
|
||||||
|
EIGEN_DEVICE_FUNC array(std::initializer_list<T> l) : dummy() {
|
||||||
|
EIGEN_UNUSED_VARIABLE(l);
|
||||||
|
eigen_assert(l.size() == 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
T dummy;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Comparison operator
|
||||||
|
// Todo: implement !=, <, <=, >, and >=
|
||||||
|
template<class T, std::size_t N>
|
||||||
|
EIGEN_DEVICE_FUNC bool operator==(const array<T,N>& lhs, const array<T,N>& rhs) {
|
||||||
|
for (std::size_t i = 0; i < N; ++i) {
|
||||||
|
if (lhs[i] != rhs[i]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
template<std::size_t I_, class T, std::size_t N>
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& array_get(array<T,N>& a) {
|
||||||
|
return a[I_];
|
||||||
|
}
|
||||||
|
template<std::size_t I_, class T, std::size_t N>
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& array_get(const array<T,N>& a) {
|
||||||
|
return a[I_];
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, std::size_t N> struct array_size<array<T,N> > {
|
||||||
|
enum { value = N };
|
||||||
|
};
|
||||||
|
template<class T, std::size_t N> struct array_size<array<T,N>& > {
|
||||||
|
enum { value = N };
|
||||||
|
};
|
||||||
|
template<class T, std::size_t N> struct array_size<const array<T,N> > {
|
||||||
|
enum { value = N };
|
||||||
|
};
|
||||||
|
template<class T, std::size_t N> struct array_size<const array<T,N>& > {
|
||||||
|
enum { value = N };
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace internal
|
||||||
|
} // end namespace Eigen
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// The compiler supports c++11, and we're not targeting cuda: use std::array as Eigen::array
|
||||||
|
#include <array>
|
||||||
|
namespace Eigen {
|
||||||
|
|
||||||
|
template <typename T, std::size_t N> using array = std::array<T, N>;
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
/* std::get is only constexpr in C++14, not yet in C++11
|
||||||
|
* - libstdc++ from version 4.7 onwards has it nevertheless,
|
||||||
|
* so use that
|
||||||
|
* - libstdc++ older versions: use _M_instance directly
|
||||||
|
* - libc++ all versions so far: use __elems_ directly
|
||||||
|
* - all other libs: use std::get to be portable, but
|
||||||
|
* this may not be constexpr
|
||||||
|
*/
|
||||||
|
#if defined(__GLIBCXX__) && __GLIBCXX__ < 20120322
|
||||||
|
#define STD_GET_ARR_HACK a._M_instance[I_]
|
||||||
|
#elif defined(_LIBCPP_VERSION)
|
||||||
|
#define STD_GET_ARR_HACK a.__elems_[I_]
|
||||||
|
#else
|
||||||
|
#define STD_GET_ARR_HACK std::template get<I_, T, N>(a)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<std::size_t I_, class T, std::size_t N> constexpr inline T& array_get(std::array<T,N>& a) { return (T&) STD_GET_ARR_HACK; }
|
||||||
|
template<std::size_t I_, class T, std::size_t N> constexpr inline T&& array_get(std::array<T,N>&& a) { return (T&&) STD_GET_ARR_HACK; }
|
||||||
|
template<std::size_t I_, class T, std::size_t N> constexpr inline T const& array_get(std::array<T,N> const& a) { return (T const&) STD_GET_ARR_HACK; }
|
||||||
|
|
||||||
|
#undef STD_GET_ARR_HACK
|
||||||
|
|
||||||
|
} // end namespace internal
|
||||||
|
} // end namespace Eigen
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // EIGEN_EMULATE_ARRAY_H
|
Loading…
x
Reference in New Issue
Block a user