File indexing completed on 2025-09-17 08:54:12
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009 #include <concepts>
0010 #include <iostream>
0011 #include <memory>
0012 #include <optional>
0013
0014 #include <covfie/core/definitions.hpp>
0015 #include <covfie/core/parameter_pack.hpp>
0016 namespace covfie::concepts {
0017 template <typename T>
0018 concept is_initial = T::is_initial == true;
0019
0020 template <typename T>
0021 concept is_constructible_from_config_and_backend = requires(
0022 const typename T::configuration_t & c,
0023 typename T::backend_t::owning_data_t & b
0024 )
0025 {
0026 {typename T::owning_data_t(c, std::move(b))};
0027 };
0028
0029 template <typename T>
0030 concept is_constructible_from_parameter_pack_len_gt1 =
0031 requires(parameter_pack<typename T::configuration_t, std::monostate> && p)
0032 {
0033 {typename T::owning_data_t(std::move(p))};
0034 };
0035
0036 template <typename T>
0037 concept is_constructible_from_parameter_pack_len_eq1 =
0038 requires(parameter_pack<typename T::configuration_t> && p)
0039 {
0040 {typename T::owning_data_t(std::move(p))};
0041 };
0042
0043 template <typename T>
0044 concept is_constructible_from_parameter_pack_self =
0045 requires(parameter_pack<typename T::owning_data_t> && p)
0046 {
0047 {typename T::owning_data_t(std::move(p))};
0048 };
0049
0050 template <typename T>
0051 concept is_constructible_from_self_rvalue =
0052 requires(typename T::owning_data_t && p)
0053 {
0054 {typename T::owning_data_t(std::move(p))};
0055 };
0056
0057 template <typename T>
0058 concept field_backend = requires
0059 {
0060
0061
0062
0063
0064 typename T::this_t;
0065
0066
0067
0068
0069
0070
0071 typename T::contravariant_input_t;
0072 typename T::covariant_output_t;
0073
0074
0075
0076
0077 typename T::owning_data_t;
0078 typename T::non_owning_data_t;
0079
0080
0081
0082
0083
0084 typename T::owning_data_t::parent_t;
0085 typename T::non_owning_data_t::parent_t;
0086
0087
0088
0089
0090
0091 requires std::is_trivially_destructible_v<typename T::non_owning_data_t>;
0092 requires
0093 std::is_trivially_copy_constructible_v<typename T::non_owning_data_t>;
0094 requires
0095 std::is_trivially_move_constructible_v<typename T::non_owning_data_t>;
0096
0097
0098
0099
0100
0101 T::is_initial;
0102 requires std::is_same_v<bool, std::decay_t<decltype(T::is_initial)>>;
0103
0104
0105
0106
0107
0108
0109
0110 typename T::configuration_t;
0111
0112 requires std::is_trivially_destructible_v<typename T::configuration_t>;
0113 requires
0114 std::is_trivially_copy_constructible_v<typename T::configuration_t>;
0115 requires
0116 std::is_trivially_move_constructible_v<typename T::configuration_t>;
0117
0118 requires requires(const typename T::owning_data_t & o)
0119 {
0120 {
0121 o.get_configuration()
0122 } -> std::same_as<typename T::configuration_t>;
0123 };
0124
0125
0126
0127
0128 requires is_initial<T> || is_constructible_from_parameter_pack_len_gt1<T>;
0129 requires !is_initial<T> || is_constructible_from_parameter_pack_len_eq1<T>;
0130 requires is_constructible_from_parameter_pack_self<T>;
0131
0132
0133
0134
0135 requires is_constructible_from_self_rvalue<T>;
0136
0137
0138
0139
0140 requires requires(std::istream & fs)
0141 {
0142 {
0143 T::owning_data_t::read_binary(fs)
0144 } -> std::same_as<typename T::owning_data_t>;
0145 };
0146
0147 requires requires(std::ostream & fs, const typename T::owning_data_t & o)
0148 {
0149 {
0150 T::owning_data_t::write_binary(fs, o)
0151 } -> std::same_as<void>;
0152 };
0153
0154 requires is_initial<T> || is_constructible_from_config_and_backend<T>;
0155
0156
0157
0158 requires requires(typename T::owning_data_t & d)
0159 {
0160 requires T::is_initial || requires
0161 {
0162 typename T::backend_t;
0163 {
0164 d.get_backend()
0165 } -> std::same_as<typename T::backend_t::owning_data_t &>;
0166 };
0167
0168 {typename T::owning_data_t(d)};
0169 {typename T::owning_data_t(std::move(d))};
0170
0171 requires requires(typename T::owning_data_t & e)
0172 {
0173 {d = e};
0174 {d = std::move(e)};
0175 };
0176 };
0177
0178 requires requires(const typename T::owning_data_t & d)
0179 {
0180
0181
0182
0183
0184 {typename T::non_owning_data_t(d)};
0185
0186
0187
0188
0189
0190 requires T::is_initial || requires
0191 {
0192 typename T::backend_t;
0193 {
0194 d.get_backend()
0195 } -> std::same_as<const typename T::backend_t::owning_data_t &>;
0196 };
0197 };
0198
0199 requires requires(typename T::non_owning_data_t & d)
0200 {
0201
0202
0203
0204
0205 requires T::is_initial || requires
0206 {
0207 typename T::backend_t;
0208 {
0209 d.get_backend()
0210 } -> std::same_as<typename T::backend_t::non_owning_data_t &>;
0211 };
0212 };
0213
0214
0215
0216
0217
0218 requires requires(const typename T::non_owning_data_t & d)
0219 {
0220 {
0221 d.at(std::declval<typename T::contravariant_input_t::vector_t>())
0222 } -> std::same_as<typename T::covariant_output_t::vector_t>;
0223
0224
0225
0226
0227
0228 requires T::is_initial || requires
0229 {
0230 typename T::backend_t;
0231 {
0232 d.get_backend()
0233 } -> std::same_as<const typename T::backend_t::non_owning_data_t &>;
0234 };
0235 };
0236 };
0237
0238 template <typename T>
0239 concept array_1d_like_field_backend = field_backend<T> && requires
0240 {
0241 typename T::vector_t;
0242
0243 requires requires(const typename T::owning_data_t & d)
0244 {
0245 {
0246 d.get_size()
0247 } -> std::unsigned_integral;
0248
0249 {
0250 d.get_host_array()
0251 } -> std::same_as<std::unique_ptr<typename T::vector_t[]>>;
0252 };
0253 };
0254
0255 template <typename T>
0256 concept vector_descriptor = true;
0257 }