File indexing completed on 2025-09-17 08:54:10
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009 #include <iostream>
0010 #include <type_traits>
0011 #include <variant>
0012
0013 #include <covfie/core/concepts.hpp>
0014 #include <covfie/core/parameter_pack.hpp>
0015 #include <covfie/core/qualifiers.hpp>
0016 #include <covfie/core/utility/binary_io.hpp>
0017 #include <covfie/core/utility/nd_size.hpp>
0018 #include <covfie/core/vector.hpp>
0019
0020 namespace covfie::backend {
0021 template <concepts::field_backend _backend_t>
0022 struct backup {
0023 using this_t = backup<_backend_t>;
0024 static constexpr bool is_initial = false;
0025
0026 using backend_t = _backend_t;
0027
0028 using contravariant_input_t = typename backend_t::contravariant_input_t;
0029 using contravariant_output_t = typename backend_t::contravariant_input_t;
0030 using covariant_input_t = typename backend_t::covariant_output_t;
0031 using covariant_output_t =
0032 covfie::vector::array_vector_d<typename covariant_input_t::vector_d>;
0033
0034 struct configuration_t {
0035 typename contravariant_input_t::vector_t min, max;
0036 typename covariant_output_t::vector_t default_value;
0037 };
0038
0039 static constexpr uint32_t IO_MAGIC_HEADER = 0xAB020001;
0040
0041 struct owning_data_t {
0042 using parent_t = this_t;
0043
0044 owning_data_t() = default;
0045 owning_data_t(const owning_data_t &) = default;
0046 owning_data_t(owning_data_t &&) = default;
0047 owning_data_t & operator=(const owning_data_t &) = default;
0048 owning_data_t & operator=(owning_data_t &&) = default;
0049
0050 template <typename... Args>
0051 explicit owning_data_t(configuration_t conf, Args... args)
0052 : m_min(conf.min)
0053 , m_max(conf.max)
0054 , m_default(conf.default_value)
0055 , m_backend(std::forward<Args>(args)...)
0056 {
0057 }
0058
0059 template <typename... Args>
0060 explicit owning_data_t(parameter_pack<configuration_t, Args...> && args)
0061 : m_min(args.x.min)
0062 , m_max(args.x.max)
0063 , m_default(args.x.default_value)
0064 , m_backend(std::move(args.xs))
0065 {
0066 }
0067
0068 explicit owning_data_t(parameter_pack<owning_data_t> && conf)
0069 : owning_data_t(std::move(conf.x))
0070 {
0071 }
0072
0073 explicit owning_data_t(
0074 const configuration_t & c, typename backend_t::owning_data_t && b
0075 )
0076 : m_min(c.min)
0077 , m_max(c.max)
0078 , m_default(c.default_value)
0079 , m_backend(std::forward<typename backend_t::owning_data_t>(b))
0080 {
0081 }
0082
0083 template <typename... Args>
0084 requires(std::same_as<
0085 typename backend_t::configuration_t,
0086 utility::nd_size<
0087 backend_t::contravariant_input_t::
0088 dimensions>>) explicit owning_data_t(Args... args)
0089 : m_backend(std::forward<Args>(args)...)
0090 {
0091 m_min.fill(static_cast<typename contravariant_input_t::scalar_t>(0)
0092 );
0093
0094 for (std::size_t i = 0; i < contravariant_input_t::dimensions; ++i)
0095 {
0096 m_max[i] = m_backend.get_configuration()[i];
0097 }
0098
0099 m_default.fill(static_cast<typename covariant_output_t::scalar_t>(0)
0100 );
0101 }
0102
0103 typename backend_t::owning_data_t & get_backend(void)
0104 {
0105 return m_backend;
0106 }
0107
0108 const typename backend_t::owning_data_t & get_backend(void) const
0109 {
0110 return m_backend;
0111 }
0112
0113 configuration_t get_configuration(void) const
0114 {
0115 return {m_min, m_max, m_default};
0116 }
0117
0118 static owning_data_t read_binary(std::istream & fs)
0119 {
0120 utility::read_io_header(fs, IO_MAGIC_HEADER);
0121
0122 auto min = utility::read_binary<decltype(m_min)>(fs);
0123 auto max = utility::read_binary<decltype(m_min)>(fs);
0124 auto def = utility::read_binary<decltype(m_default)>(fs);
0125 typename backend_t::owning_data_t be =
0126 backend_t::owning_data_t::read_binary(fs);
0127
0128 utility::read_io_footer(fs, IO_MAGIC_HEADER);
0129
0130 return owning_data_t(configuration_t{min, max, def}, std::move(be));
0131 }
0132
0133 static void write_binary(std::ostream & fs, const owning_data_t & o)
0134 {
0135 utility::write_io_header(fs, IO_MAGIC_HEADER);
0136
0137 fs.write(
0138 reinterpret_cast<const char *>(&o.m_min),
0139 sizeof(decltype(m_min))
0140 );
0141 fs.write(
0142 reinterpret_cast<const char *>(&o.m_max),
0143 sizeof(decltype(m_max))
0144 );
0145 fs.write(
0146 reinterpret_cast<const char *>(&o.m_default),
0147 sizeof(decltype(m_default))
0148 );
0149
0150 backend_t::owning_data_t::write_binary(fs, o.m_backend);
0151
0152 utility::write_io_footer(fs, IO_MAGIC_HEADER);
0153 }
0154
0155 typename contravariant_input_t::vector_t m_min, m_max;
0156 typename covariant_output_t::vector_t m_default;
0157 typename backend_t::owning_data_t m_backend;
0158 };
0159
0160 struct non_owning_data_t {
0161 using parent_t = this_t;
0162
0163 non_owning_data_t(const owning_data_t & src)
0164 : m_min(src.m_min)
0165 , m_max(src.m_max)
0166 , m_default(src.m_default)
0167 , m_backend(src.m_backend)
0168 {
0169 }
0170
0171 COVFIE_HOST_DEVICE typename covariant_output_t::vector_t
0172 at(typename contravariant_input_t::vector_t coord) const
0173 {
0174 for (std::size_t i = 0; i < contravariant_input_t::dimensions; ++i)
0175 {
0176 if (coord[i] < m_min[i] || coord[i] > m_max[i]) {
0177 return m_default;
0178 }
0179 }
0180
0181 return m_backend.at(coord);
0182 }
0183
0184 typename backend_t::non_owning_data_t & get_backend(void)
0185 {
0186 return m_backend;
0187 }
0188
0189 const typename backend_t::non_owning_data_t & get_backend(void) const
0190 {
0191 return m_backend;
0192 }
0193
0194 typename contravariant_input_t::vector_t m_min, m_max;
0195 typename covariant_output_t::vector_t m_default;
0196 typename backend_t::non_owning_data_t m_backend;
0197 };
0198 };
0199 }