Lagrange
create_array.h
1/*
2 * Copyright 2020 Adobe. All rights reserved.
3 * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License. You may obtain a copy
5 * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 *
7 * Unless required by applicable law or agreed to in writing, software distributed under
8 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 * OF ANY KIND, either express or implied. See the License for the specific language
10 * governing permissions and limitations under the License.
11 */
12#pragma once
13
14#include <lagrange/common.h>
15#include <lagrange/experimental/Array.h>
16
17namespace lagrange {
18namespace experimental {
19
20// `create_array` will take up ownership of the data, thus data is copied into
21// the array data structure.
22//
23// In contrast, `wrap_with_array` will not take ownership of the data and no
24// copy is performed. However, it assumes data stays valid through its life
25// time.
26
27template <typename Derived>
28std::unique_ptr<ArrayBase> create_array(const Eigen::MatrixBase<Derived>& matrix)
29{
30 using EvalType = std::decay_t<decltype(matrix.eval())>;
31 return std::make_unique<EigenArray<EvalType>>(matrix);
32}
33
34template <typename Derived>
35std::unique_ptr<ArrayBase> create_array(const Eigen::ArrayBase<Derived>& array)
36{
37 return create_array(array.matrix());
38}
39
40template <typename Derived>
41std::unique_ptr<ArrayBase> create_array(Eigen::PlainObjectBase<Derived>&& matrix)
42{
43 static_assert(!std::is_const<Derived>::value, "Derived should not be const!");
44#ifndef NDEBUG
45 const void* ptr = matrix.data();
46#endif
47 auto r = std::make_unique<EigenArray<Derived>>(std::move(matrix.derived()));
48#ifndef NDEBUG
49 const void* ptr2 = r->data();
50 la_runtime_assert(ptr == ptr2, "Data is copied when it should have been moved.");
51#endif
52 return r;
53}
54
55template <typename Scalar, typename Index, int Options = Eigen::RowMajor>
56std::unique_ptr<ArrayBase> create_array(Scalar* values, Index rows, Index cols)
57{
58 using EigenType = Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, Options>;
59 return std::make_unique<EigenArray<EigenType>>(Eigen::Map<EigenType>(values, rows, cols));
60}
61
62static inline std::shared_ptr<ArrayBase> create_array(std::shared_ptr<ArrayBase> array_ptr)
63{
64 return array_ptr;
65}
66
67template <typename Derived>
68std::unique_ptr<ArrayBase> wrap_with_array(Eigen::PlainObjectBase<Derived>& matrix)
69{
70 static_assert(!std::is_const<Derived>::value, "Derived should not be const!");
71 return std::make_unique<EigenArrayRef<Derived>>(matrix);
72}
73
74template <typename Derived>
75std::unique_ptr<const ArrayBase> wrap_with_array(const Eigen::PlainObjectBase<Derived>& matrix)
76{
77 static_assert(!std::is_const<Derived>::value, "Derived should not be const!");
78 return std::make_unique<EigenArrayRef<const Derived>>(matrix);
79}
80
81template <typename Derived>
82std::unique_ptr<ArrayBase> wrap_with_array(const Eigen::PlainObjectBase<Derived>&& /*matrix*/)
83{
84 static_assert(
85 StaticAssertableBool<Derived>::False,
86 "Lagrange Array cannot wrap around r-value Eigen matrix "
87 "because its memory may be invalid after the creation.");
88 return nullptr;
89}
90
91template <typename Derived, int Options, typename StrideType>
92std::enable_if_t<!std::is_const<Derived>::value, std::unique_ptr<ArrayBase>> wrap_with_array(
93 Eigen::Map<Derived, Options, StrideType>& matrix)
94{
95 static_assert(!std::is_const<Derived>::value, "Derived should not be const!");
96 return std::make_unique<RawArray<
97 typename Derived::Scalar,
98 Derived::RowsAtCompileTime,
99 Derived::ColsAtCompileTime,
100 Derived::Options>>(matrix.data(), matrix.rows(), matrix.cols());
101}
102
103template <typename Derived, int Options, typename StrideType>
104std::enable_if_t<std::is_const<Derived>::value, std::unique_ptr<const ArrayBase>> wrap_with_array(
105 const Eigen::Map<Derived, Options, StrideType>& matrix)
106{
107 return std::make_unique<const RawArray<
108 const typename Derived::Scalar,
109 Derived::RowsAtCompileTime,
110 Derived::ColsAtCompileTime,
111 Derived::Options>>(matrix.data(), matrix.rows(), matrix.cols());
112}
113
114template <typename Derived, int Options, typename StrideType>
115std::enable_if_t<!std::is_const<Derived>::value, std::unique_ptr<ArrayBase>> wrap_with_array(
116 Eigen::Map<Derived, Options, StrideType>&& matrix)
117{
118 return std::make_unique<RawArray<
119 typename Derived::Scalar,
120 Derived::RowsAtCompileTime,
121 Derived::ColsAtCompileTime,
122 Derived::Options>>(matrix.data(), matrix.rows(), matrix.cols());
123}
124
125template <typename Derived, int Options, typename StrideType>
126std::enable_if_t<std::is_const<Derived>::value, std::unique_ptr<const ArrayBase>> wrap_with_array(
127 const Eigen::Map<Derived, Options, StrideType>&& matrix)
128{
129 return std::make_unique<const RawArray<
130 const typename Derived::Scalar,
131 Derived::RowsAtCompileTime,
132 Derived::ColsAtCompileTime,
133 Derived::Options>>(matrix.data(), matrix.rows(), matrix.cols());
134}
135
136template <
137 typename Scalar,
138 typename Index,
139 int Rows = Eigen::Dynamic,
140 int Cols = Eigen::Dynamic,
141 int Options = Eigen::RowMajor>
142std::unique_ptr<ArrayBase> wrap_with_array(Scalar* values, Index rows, Index cols)
143{
144 return std::make_unique<RawArray<Scalar, Rows, Cols, Options>>(values, rows, cols);
145}
146
147template <
148 typename Scalar,
149 typename Index,
150 int Rows = Eigen::Dynamic,
151 int Cols = Eigen::Dynamic,
152 int Options = Eigen::RowMajor>
153std::unique_ptr<const ArrayBase> wrap_with_array(const Scalar* values, Index rows, Index cols)
154{
155 return std::make_unique<const RawArray<const Scalar, Rows, Cols, Options>>(values, rows, cols);
156}
157
158
159} // namespace experimental
160} // namespace lagrange
#define la_runtime_assert(...)
Runtime assertion check.
Definition: assert.h:169
Main namespace for Lagrange.
Definition: AABBIGL.h:30