6namespace opcua::detail {
8template <
typename... Ts>
9struct Overload : Ts... {
10 using Ts::operator()...;
13template <
typename... Ts>
14Overload(Ts...) -> Overload<Ts...>;
17struct AlwaysFalse : std::false_type {};
19template <
typename T,
typename... Ts>
20using IsOneOf = std::disjunction<std::is_same<T, Ts>...>;
26template <
typename C,
typename T>
27struct MemberType<T C::*> {
32using MemberTypeT =
typename MemberType<T>::type;
35using RangeIteratorT =
decltype(std::begin(std::declval<T&>()));
38using RangeValueT =
typename std::iterator_traits<RangeIteratorT<T>>::value_type;
40template <
typename,
typename =
void>
41struct HasBegin : std::false_type {};
44struct HasBegin<T, std::void_t<decltype(std::begin(std::declval<T&>()))>> : std::true_type {};
46template <
typename,
typename =
void>
47struct HasEnd : std::false_type {};
50struct HasEnd<T, std::void_t<decltype(std::end(std::declval<T&>()))>> : std::true_type {};
52template <
typename,
typename =
void>
53struct HasData : std::false_type {};
56struct HasData<T, std::void_t<decltype(std::data(std::declval<T&>()))>> : std::true_type {};
58template <
typename,
typename =
void>
59struct HasDataPointer : std::false_type {};
62struct HasDataPointer<T, std::void_t<decltype(std::data(std::declval<T&>()))>>
63 : std::is_pointer<decltype(std::data(std::declval<T&>()))> {};
65template <
typename,
typename =
void>
66struct HasSize : std::false_type {};
69struct HasSize<T, std::void_t<decltype(std::size(std::declval<T&>()))>> : std::true_type {};
72struct IsRange : std::conjunction<HasBegin<T>, HasEnd<T>> {};
75struct IsContiguousRange : std::conjunction<IsRange<T>, HasDataPointer<T>, HasSize<T>> {};