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