userver: userver/formats/common/meta.hpp Source File
Loading...
Searching...
No Matches
meta.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/formats/common/meta.hpp
4/// @brief Metaprogramming helpers for converters detection.
5/// @ingroup userver_universal
6
7#include <type_traits>
8
9#include <userver/formats/parse/to.hpp>
10#include <userver/formats/serialize/to.hpp>
11#include <userver/utils/meta_light.hpp>
12
13USERVER_NAMESPACE_BEGIN
14
15namespace formats::common {
16
17namespace impl {
18
19/// `kHasX` are only intended for internal diagnostic use!
20///
21/// `formats` doesn't support SFINAE, so e.g. `kHasParse` can return `true`
22/// while a usage of `Parse` will fail to compile.
23
24template <typename Value, typename T>
25using HasParse = decltype(Parse(std::declval<const Value&>(), parse::To<T>{}));
26
27template <typename Value, typename T>
28using HasSerialize = decltype(Serialize(std::declval<const T&>(), serialize::To<Value>{}));
29
30template <typename Value, typename T>
31using HasConvert = decltype(Convert(std::declval<const Value&>(), parse::To<T>{}));
32
33template <typename Value>
34using IsFormatValue = typename Value::ParseException;
35
36template <class Value, class T>
37constexpr inline bool kHasParse = meta::kIsDetected<HasParse, Value, T>;
38
39template <class Value, class T>
40constexpr inline bool kHasSerialize = meta::kIsDetected<HasSerialize, Value, T>;
41
42template <class Value, class T>
43constexpr inline bool kHasConvert = meta::kIsDetected<HasConvert, Value, T>;
44
45} // namespace impl
46
47/// Used in `Parse` overloads that are templated on `Value`, avoids clashing
48/// with `Parse` from string
49template <class Value>
51
52// Unwraps a transient type - tag types, for which ADL-found `Parse` returns
53// another type, not the type specified in `formats::parse::To`. For example,
54// there can be a `IntegerWithMin<42>` type that checks that the value contains
55// a number `>= 42`, then parses and returns an `int`.
56//
57// For a normal type T, just returns the type T itself.
58template <typename Value, typename T>
59using ParseType = decltype(Parse(std::declval<Value>(), parse::To<T>()));
60
61} // namespace formats::common
62
63USERVER_NAMESPACE_END