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.
132 lines
2.8 KiB
132 lines
2.8 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>; |
|
};
|
|
|