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
150template <
typename Tp>
151struct is_string_type : impl::is_string_type<unqualified_identity_t<Tp>>
171ROCPROFILER_IMPL_HAS_CONCEPT(has_traits, traits_type)
172ROCPROFILER_IMPL_HAS_CONCEPT(has_value_type, value_type)
173ROCPROFILER_IMPL_HAS_CONCEPT(has_key_type, key_type)
174ROCPROFILER_IMPL_HAS_CONCEPT(has_mapped_type, mapped_type)
176ROCPROFILER_IMPL_SFINAE_CONCEPT(has_empty_member_function, std::declval<Tp>().empty())
177ROCPROFILER_IMPL_SFINAE_CONCEPT(can_stringify,
std::declval<
std::ostream&>() <<
std::declval<Tp>())
178ROCPROFILER_IMPL_SFINAE_CONCEPT(is_iterable,
179 std::begin(
std::declval<Tp>()),
180 std::end(
std::declval<Tp>()))
183template <typename Tp>
184using supports_ostream = can_stringify<Tp>;
186template <typename ArgT>
190 using arg_type = unqualified_identity_t<ArgT>;
192 if constexpr(has_empty_member_function<arg_type>::value)
194 return std::forward<ArgT>(_v).empty();
196 else if constexpr(is_string_type<arg_type>::value)
198 static_assert(std::is_constructible<std::string_view, ArgT>::value,
199 "not string_view constructible");
200 return std::string_view{std::forward<ArgT>(_v)}.empty();
208template <
typename ContainerT,
typename... Args>
210emplace(ContainerT& _c,
int, Args&&... _args)
211 ->
decltype(_c.emplace_back(std::forward<Args>(_args)...))
213 return _c.emplace_back(std::forward<Args>(_args)...);
216template <
typename ContainerT,
typename... Args>
218emplace(ContainerT& _c,
long, Args&&... _args) ->
decltype(_c.emplace(std::forward<Args>(_args)...))
220 return _c.emplace(std::forward<Args>(_args)...);
223template <
typename ContainerT,
typename ArgT>
225reserve(ContainerT& _c,
int, ArgT _arg) ->
decltype(_c.reserve(_arg), bool())
231template <
typename ContainerT,
typename ArgT>
233reserve(ContainerT&,
long, ArgT)
239template <
typename ContainerT,
typename... Args>
241emplace(ContainerT& _c, Args&&... _args)
243 return impl::emplace(_c, 0, std::forward<Args>(_args)...);
246template <
typename ContainerT,
typename ArgT>
248reserve(ContainerT& _c, ArgT _arg)
250 return impl::reserve(_c, 0, _arg);
253template <
typename Tp>
256 static constexpr auto value =
false;
262#undef ROCPROFILER_IMPL_HAS_CONCEPT
263#undef ROCPROFILER_IMPL_SFINAE_CONCEPT