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 <class Value, class T>
25concept HasParse = requires(const Value& value) { Parse(value, parse::To<T>{}); };
26
27template <class Value, class T>
28concept HasSerialize = requires(const T& x) { Serialize(x, serialize::To<Value>{}); };
29
30template <class Value, class T>
31concept HasConvert = requires(const Value& value) { Convert(value, parse::To<T>{}); };
32
33} // namespace impl
34
35/// Used in `Parse` overloads that are templated on `Value`, avoids clashing
36/// with `Parse` from string
37template <class Value>
38concept kIsFormatValue = requires { typename Value::ParseException; }; // NOLINT(readability-identifier-naming)
39
40// Unwraps a transient type - tag types, for which ADL-found `Parse` returns
41// another type, not the type specified in `formats::parse::To`. For example,
42// there can be a `IntegerWithMin<42>` type that checks that the value contains
43// a number `>= 42`, then parses and returns an `int`.
44//
45// For a normal type T, just returns the type T itself.
46template <typename Value, typename T>
47using ParseType = decltype(Parse(std::declval<Value>(), parse::To<T>()));
48
49} // namespace formats::common
50
51USERVER_NAMESPACE_END