34#define ROCPROFILER_IMPL_HAS_CONCEPT(NAME, TRAIT) \
35 template <typename Tp, typename = typename Tp::TRAIT> \
36 inline constexpr bool NAME(int) \
41 template <typename Tp> \
42 inline constexpr bool NAME(long) \
47#define ROCPROFILER_IMPL_SFINAE_CONCEPT(NAME, ...) \
48 template <typename Tp> \
52 static constexpr auto sfinae(int) -> decltype(__VA_ARGS__, bool()) { return true; } \
54 static constexpr auto sfinae(long) { return false; } \
57 static constexpr bool value = sfinae(0); \
58 constexpr auto operator()() const { return sfinae(0); } \
68struct unqualified_identity
70 using type = std::remove_cv_t<std::remove_reference_t<std::decay_t<Tp>>>;
74using unqualified_identity_t =
typename unqualified_identity<Tp>::type;
76template <
typename Tp,
typename Up>
77struct is_same_unqualified_identity
78: std::is_same<unqualified_identity_t<Tp>, unqualified_identity_t<Up>>
85 using return_type = void;
87 static constexpr auto value =
false;
88 static constexpr void default_value() {}
92struct string_support<const char*>
94 using type =
const char*;
95 using return_type = type;
97 static constexpr auto value =
true;
98 static constexpr type default_value() {
return nullptr; }
100 type operator()(
const char* val)
const {
return val; }
104struct string_support<
std::string_view>
106 using type = std::string_view;
107 using return_type = type;
109 static constexpr auto value =
true;
110 static constexpr type default_value() {
return type{}; }
112 type operator()(
const char* val)
const {
return type{val}; }
116struct string_support<
std::string>
118 using type = std::string;
119 using return_type = type;
121 static constexpr auto value =
true;
122 static type default_value() {
return type{}; }
124 type operator()(
const char* val)
const {
return type{val}; }
129template <
typename Tp>
130struct is_string_type : std::false_type
134struct is_string_type<
std::string> : std::true_type
138struct is_string_type<char*> : std::true_type
142struct is_string_type<const char*> : std::true_type
146struct is_string_type<
std::string_view> : std::true_type
149template <
typename Tp>
150struct is_optional : std::false_type
153template <
typename Tp>
154struct is_optional<
std::optional<Tp>> : std::true_type
158template <
typename Tp>
159struct is_string_type : impl::is_string_type<unqualified_identity_t<Tp>>
162template <
typename Tp>
163struct is_optional : impl::is_optional<unqualified_identity_t<Tp>>
183ROCPROFILER_IMPL_HAS_CONCEPT(has_traits, traits_type)
184ROCPROFILER_IMPL_HAS_CONCEPT(has_value_type, value_type)
185ROCPROFILER_IMPL_HAS_CONCEPT(has_key_type, key_type)
186ROCPROFILER_IMPL_HAS_CONCEPT(has_mapped_type, mapped_type)
188ROCPROFILER_IMPL_SFINAE_CONCEPT(has_empty_member_function, std::declval<Tp>().empty())
189ROCPROFILER_IMPL_SFINAE_CONCEPT(can_stringify,
std::declval<
std::ostream&>() <<
std::declval<Tp>())
190ROCPROFILER_IMPL_SFINAE_CONCEPT(is_iterable,
191 std::begin(
std::declval<Tp>()),
192 std::end(
std::declval<Tp>()))
195template <typename Tp>
196using supports_ostream = can_stringify<Tp>;
198template <typename ArgT>
202 using arg_type = unqualified_identity_t<ArgT>;
204 if constexpr(has_empty_member_function<arg_type>::value)
206 return std::forward<ArgT>(_v).empty();
208 else if constexpr(is_string_type<arg_type>::value)
210 static_assert(std::is_constructible<std::string_view, ArgT>::value,
211 "not string_view constructible");
212 return std::string_view{std::forward<ArgT>(_v)}.empty();
220template <
typename ContainerT,
typename... Args>
222emplace(ContainerT& _c,
int, Args&&... _args)
223 ->
decltype(_c.emplace_back(std::forward<Args>(_args)...))
225 return _c.emplace_back(std::forward<Args>(_args)...);
228template <
typename ContainerT,
typename... Args>
230emplace(ContainerT& _c,
long, Args&&... _args) ->
decltype(_c.emplace(std::forward<Args>(_args)...))
232 return _c.emplace(std::forward<Args>(_args)...);
235template <
typename ContainerT,
typename ArgT>
237reserve(ContainerT& _c,
int, ArgT _arg) ->
decltype(_c.reserve(_arg), bool())
243template <
typename ContainerT,
typename ArgT>
245reserve(ContainerT&,
long, ArgT)
251template <
typename ContainerT,
typename... Args>
253emplace(ContainerT& _c, Args&&... _args)
255 return impl::emplace(_c, 0, std::forward<Args>(_args)...);
258template <
typename ContainerT,
typename ArgT>
260reserve(ContainerT& _c, ArgT _arg)
262 return impl::reserve(_c, 0, _arg);
265template <
typename Tp>
268 static constexpr auto value =
false;
274#undef ROCPROFILER_IMPL_HAS_CONCEPT
275#undef ROCPROFILER_IMPL_SFINAE_CONCEPT