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 =
29 decltype(Serialize(std::declval<const T&>(), serialize::To<Value>{}));
30
31template <typename Value, typename T>
32using HasConvert =
33 decltype(Convert(std::declval<const Value&>(), parse::To<T>{}));
34
35template <typename Value>
36using IsFormatValue = typename Value::ParseException;
37
38template <class Value, class T>
39constexpr inline bool kHasParse = meta::kIsDetected<HasParse, Value, T>;
40
41template <class Value, class T>
42constexpr inline bool kHasSerialize = meta::kIsDetected<HasSerialize, Value, T>;
43
44template <class Value, class T>
45constexpr inline bool kHasConvert = meta::kIsDetected<HasConvert, Value, T>;
46
47} // namespace impl
48
49/// Used in `Parse` overloads that are templated on `Value`, avoids clashing
50/// with `Parse` from string
51template <class Value>
52constexpr inline bool kIsFormatValue =
54
55// Unwraps a transient type - tag types, for which ADL-found `Parse` returns
56// another type, not the type specified in `formats::parse::To`. For example,
57// there can be a `IntegerWithMin<42>` type that checks that the value contains
58// a number `>= 42`, then parses and returns an `int`.
59//
60// For a normal type T, just returns the type T itself.
61template <typename Value, typename T>
62using ParseType = decltype(Parse(std::declval<Value>(), parse::To<T>()));
63
64} // namespace formats::common
65
66USERVER_NAMESPACE_END