You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

143 lines
3.0 KiB

#pragma once
#include "ParseArgs.h"
#include <concepts>
class BaseParameters;
using michlib::real;
template<class T>
concept InfoSupported = requires(T t) {
{
t.Info()
} -> std::convertible_to<MString>;
};
template<class T>
concept ParametersRequiredRegion = requires(T t, michlib_internal::ParameterListEx& pars, const CLArgs& args, const struct Region& r) {
{
t.Parameters(pars, args, r).first
} -> std::convertible_to<const BaseParameters*>;
};
template<class T>
concept ParametersNotRequiredRegion = requires(T t, michlib_internal::ParameterListEx& pars, const CLArgs& args) {
{
t.Parameters(pars, args).first
} -> std::convertible_to<const BaseParameters*>;
};
template<class T>
concept ParametersSupported = ParametersRequiredRegion<T> || ParametersNotRequiredRegion<T>;
template<class T>
concept ReadPSupported = requires(T t, const MString& vname, const BaseParameters* ip, size_t i) {
{
t.Read(vname, ip, i)(0)
} -> std::convertible_to<real>;
};
template<class T>
concept ReadSupported = requires(T t, const MString& vname, size_t i) {
{
t.Read(vname, i)(0)
} -> std::convertible_to<real>;
};
template<class T>
concept IsUVData = requires(T t) {
{
t.U(0)
} -> std::convertible_to<real>;
{
t.V(0)
} -> std::convertible_to<real>;
{
t.U2(0)
} -> std::convertible_to<real>;
};
namespace internal
{
template<class T>
concept HaveXYStep = requires(T t) {
{
t.XStep()
} -> std::convertible_to<real>;
{
t.YStep()
} -> std::convertible_to<real>;
};
template<typename...> using void_ = void;
template<class D, bool RP, bool R> struct GetReadType_;
template<class D, bool R> struct GetReadType_<D, true, R>
{
using p = BaseParameters*;
using type = decltype(D().Read(MString(), p(), 0));
};
template<class D> struct GetReadType_<D, false, true>
{
using type = decltype(D().Read(MString(), 0));
};
template<class T>
concept HaveDisable = requires(T t) {
{
T::disabledactions
} -> std::convertible_to<const char*>;
};
consteval bool cmpspace(const char* s1, const char* s2)
{
size_t i = 0;
while(true)
{
if(s1[i] != s2[i]) return false;
i++;
if(s1[i] == 0 && (s2[i] == 0 || s2[i] == ' ')) return true;
if(s1[i] == 0 || s2[i] == 0 || s2[i] == ' ') return false;
}
return false;
}
} // namespace internal
template<class Act, class S> consteval bool IsDisabled()
{
if constexpr(!internal::HaveDisable<S>)
return false;
else
{
bool prsp = true;
size_t i = 0;
do {
if(prsp && internal::cmpspace(Act::name, S::disabledactions + i)) return true;
prsp = S::disabledactions[i] == ' ';
} while(S::disabledactions[++i] != 0);
return false;
}
}
template<class D> using ReadType = internal::GetReadType_<D, ReadPSupported<D>, ReadSupported<D>>::type;
template<class T>
concept ReadIsGrid = requires {
{
ReadType<T>().XStep()
} -> std::convertible_to<real>;
{
ReadType<T>().YStep()
} -> std::convertible_to<real>;
};
template<class T>
concept ReadIs2DGeoRectArray = requires {
{
ReadType<T>().Ix2Lon(0)
} -> std::convertible_to<real>;
{
ReadType<T>().Iy2Lat(0)
} -> std::convertible_to<real>;
};