Reaktoro  v2.11.0
A unified framework for modeling chemically reactive systems
ArraySerialization.hpp
1 // Reaktoro is a unified framework for modeling chemically reactive systems.
2 //
3 // Copyright © 2014-2024 Allan Leal
4 //
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 of the License, or (at your option) any later version.
9 //
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with this library. If not, see <http://www.gnu.org/licenses/>.
17 
18 #pragma once
19 
20 // Reaktoro includes
21 #include <Reaktoro/Common/TraitsUtils.hpp>
22 #include <Reaktoro/Common/Matrix.hpp>
23 
24 namespace Reaktoro {
25 namespace detail {
26 
27 template<typename T>
28 struct isArrayAux;
29 
30 template<typename T>
31 constexpr auto isArray = isArrayAux<Decay<T>>::value;
32 
33 template<typename T>
34 struct isArrayAux : std::false_type {};
35 
36 template<typename Scalar, int Rows, int Options, int MaxRows>
37 struct isArrayAux<Eigen::Array<Scalar, Rows, 1, Options, MaxRows, 1>> : std::true_type {};
38 
39 template<typename Scalar, int Cols, int Options, int MaxCols>
40 struct isArrayAux<Eigen::Array<Scalar, 1, Cols, Options, 1, MaxCols>> : std::true_type {};
41 
42 template<typename Scalar, int Rows, int Options, int MaxRows>
43 struct isArrayAux<Eigen::Matrix<Scalar, Rows, 1, Options, MaxRows, 1>> : std::true_type {};
44 
45 template<typename Scalar, int Cols, int Options, int MaxCols>
46 struct isArrayAux<Eigen::Matrix<Scalar, 1, Cols, Options, 1, MaxCols>> : std::true_type {};
47 
48 template<typename Vec, int Size>
49 struct isArrayAux<Eigen::VectorBlock<Vec, Size>> : isArrayAux<Decay<Vec>> {};
50 
51 template<typename Vec>
52 struct isArrayAux<Eigen::Ref<Vec>> : isArrayAux<Decay<Vec>> {};
53 
55 template<typename Arg>
56 constexpr auto length(const Arg& x) -> std::size_t
57 {
58  if constexpr(isArray<Arg>)
59  return x.size();
60  else return 1;
61 }
62 
63 template<typename Arg, typename... Args>
64 constexpr auto length(const Arg& x, const Args&... xs) -> std::size_t
65 {
66  if constexpr(sizeof...(Args) > 0)
67  return length(x) + length(xs...);
68  else return length(x);
69 }
70 
71 template<typename Array, typename Arg>
72 constexpr auto serialize(Array& array, std::size_t pos, const Arg& x) -> void
73 {
74  using U = Decay<decltype(array[0])>;
75 
76  if constexpr(isArray<Arg>)
77  {
78  assert(array.size() >= pos + x.size());
79  array.segment(pos, x.size()) = x.template cast<U>();
80  }
81  else
82  {
83  assert(array.size() >= pos + 1);
84  array[pos] = static_cast<U>(x);
85  }
86 }
87 
88 template<typename Array, typename Arg, typename... Args>
89 constexpr auto serialize(Array& array, std::size_t pos, const Arg& x, const Args&... xs) -> void
90 {
91  serialize(array, pos, x);
92  if constexpr(sizeof...(Args) > 0)
93  serialize(array, pos + length(x), xs...);
94 }
95 
96 template<typename Array, typename Arg>
97 constexpr auto deserialize(const Array& array, std::size_t pos, Arg& x) -> void
98 {
99  if constexpr(isArray<Arg>)
100  {
101  assert(array.size() >= pos + x.size());
102  x = array.segment(pos, x.size());
103  }
104  else
105  {
106  assert(array.size() >= pos + 1);
107  x = array[pos];
108  }
109 }
110 
111 template<typename Array, typename Arg, typename... Args>
112 constexpr auto deserialize(const Array& array, std::size_t pos, Arg& x, Args&... xs) -> void
113 {
114  deserialize(array, pos, x);
115  if constexpr(sizeof...(Args) > 0)
116  deserialize(array, pos + length(x), xs...);
117 }
118 
119 } // namespace detail
120 
123 {
125  template<typename Array, typename... Args>
126  constexpr static auto resize(Array& array, const Args&... args) -> void
127  {
128  const auto size = detail::length(args...);
129  array.resize(size);
130  }
131 
133  template<typename Array, typename... Args>
134  constexpr static auto serialize(Array& array, const Args&... args) -> void
135  {
136  detail::serialize(array, 0, args...);
137  }
138 
140  template<typename Array, typename... Args>
141  constexpr static auto deserialize(const Array& array, Args&... args) -> void
142  {
143  detail::deserialize(array, 0, args...);
144  }
145 };
146 
147 } // namespace Reaktoro
The namespace containing all components of the Reaktoro library.
Definition: Algorithms.hpp:29
std::array< T, N > Array
Convenient alias for std::array<T, N>.
Definition: Types.hpp:62
The class implementing methods to serialize/deserialize data into/from arrays.
Definition: ArraySerialization.hpp:123
constexpr static auto serialize(Array &array, const Args &... args) -> void
Copy the data in args into array.
Definition: ArraySerialization.hpp:134
constexpr static auto resize(Array &array, const Args &... args) -> void
Resize array so that it can store the data in args.
Definition: ArraySerialization.hpp:126
constexpr static auto deserialize(const Array &array, Args &... args) -> void
Copy the data in array to args.
Definition: ArraySerialization.hpp:141
Definition: TraitsUtils.hpp:100
Definition: ArraySerialization.hpp:34