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
12USERVER_NAMESPACE_BEGIN
13
14namespace formats::common {
15
16namespace impl {
17
18/// `kHasX` are only intended for internal diagnostic use!
19///
20/// `formats` doesn't support SFINAE, so e.g. `kHasParse` can return `true`
21/// while a usage of `Parse` will fail to compile.
22
23template <class Value, class T>
24concept HasParse = requires(const Value& value) { Parse(value, parse::To<T>{}); };
25
26template <class Value, class T>
27concept HasSerialize = requires(const T& x) { Serialize(x, serialize::To<Value>{}); };
28
29template <class Value, class T>
30concept HasConvert = requires(const Value& value) { Convert(value, parse::To<T>{}); };
31
32} // namespace impl
33
34/// Used in `Parse` overloads that are templated on `Value`, avoids clashing
35/// with `Parse` from string
36template <class Value>
37concept IsFormatValue = requires { typename Value::ParseException; };
38
39/// @deprecated Use @ref formats::common::IsFormatValue instead.
40template <class Value>
41concept kIsFormatValue = IsFormatValue<Value>; // NOLINT(readability-identifier-naming)
42
43// Unwraps a transient type - tag types, for which ADL-found `Parse` returns
44// another type, not the type specified in `formats::parse::To`. For example,
45// there can be a `IntegerWithMin<42>` type that checks that the value contains
46// a number `>= 42`, then parses and returns an `int`.
47//
48// For a normal type T, just returns the type T itself.
49template <typename Value, typename T>
50using ParseType = decltype(Parse(std::declval<Value>(), parse::To<T>()));
51
52} // namespace formats::common
53
54USERVER_NAMESPACE_END