timemory 3.3.0
Modular C++ Toolkit for Performance Analysis and Logging. Profiling API and Tools for C, C++, CUDA, Fortran, and Python. The C++ template API is essentially a framework to creating tools: it is designed to provide a unifying interface for recording various performance measurements alongside data logging and interfaces to other tools.
base_bundle.hpp
Go to the documentation of this file.
1// MIT License
2//
3// Copyright (c) 2020, The Regents of the University of California,
4// through Lawrence Berkeley National Laboratory (subject to receipt of any
5// required approvals from the U.S. Dept. of Energy). All rights reserved.
6//
7// Permission is hereby granted, free of charge, to any person obtaining a copy
8// of this software and associated documentation files (the "Software"), to deal
9// in the Software without restriction, including without limitation the rights
10// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11// copies of the Software, and to permit persons to whom the Software is
12// furnished to do so, subject to the following conditions:
13//
14// The above copyright notice and this permission notice shall be included in all
15// copies or substantial portions of the Software.
16//
17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23// SOFTWARE.
24
25#pragma once
26
36
37#include <atomic>
38#include <bitset>
39#include <cstdint>
40#include <sstream>
41#include <string>
42#include <tuple>
43#include <utility>
44
45namespace tim
46{
47//
48namespace operation
49{
50template <typename Op, typename Tag, typename... Types>
51struct generic_operator<quirk::config<Types...>, Op, Tag>
52{
53 TIMEMORY_DEFAULT_OBJECT(generic_operator)
54
55 template <typename Arg, typename... Args>
56 explicit generic_operator(Arg&&, Args&&...)
57 {}
58
59 template <typename... Args>
60 auto operator()(Args&&...) const
61 {}
62};
63//
64template <typename... Types>
65struct generic_counter<quirk::config<Types...>>
66{
67 TIMEMORY_DEFAULT_OBJECT(generic_counter)
68
69 template <typename Arg, typename... Args>
70 explicit generic_counter(Arg&&, Args&&...)
71 {}
72
73 template <typename... Args>
74 auto operator()(Args&&...) const
75 {}
76};
77//
78template <typename... Types>
79struct generic_deleter<quirk::config<Types...>>
80{
81 TIMEMORY_DEFAULT_OBJECT(generic_deleter)
82
83 template <typename Arg, typename... Args>
84 explicit generic_deleter(Arg&&, Args&&...)
85 {}
86
87 template <typename... Args>
88 auto operator()(Args&&...) const
89 {}
90};
91//
92} // namespace operation
93//
94namespace impl
95{
96//
97class common_base_bundle
98{
99public:
100 // public alias section
101 using size_type = int64_t;
102 using string_t = string_view_t;
103 using captured_location_t = source_location::captured;
104
105protected:
106 // protected construction / destruction section
107 TIMEMORY_DEFAULT_OBJECT(common_base_bundle)
108
109 common_base_bundle(scope::config&& _config, hash_value_t _hash)
110 : m_scope(_config)
111 , m_hash(_hash)
112 {}
113
114public:
115 // public member function section
116 hash_value_t hash() const { return m_hash; }
117 int64_t laps() const { return m_laps; }
118 bool store() const { return m_store(); }
119 std::string key() const { return std::string{ get_hash_identifier(m_hash) }; }
120
121 bool get_store() const { return m_store(); }
122 hash_value_t get_hash() const { return m_hash; }
123 int64_t get_laps() const { return m_laps; }
124 const scope::config& get_scope() const { return m_scope; }
125
126 void store(bool v) { m_store(v); }
127 void set_store(bool v) { m_store(v); }
128 void set_laps(int64_t v) { m_laps = v; }
129
130 common_base_bundle& operator+=(const common_base_bundle& rhs)
131 {
132 m_laps += rhs.m_laps;
133 return *this;
134 }
135
136 common_base_bundle& operator-=(const common_base_bundle& rhs)
137 {
138 m_laps -= rhs.m_laps;
139 return *this;
140 }
141
142protected:
143 scope::config m_scope = scope::get_default();
144 hash_value_t m_hash = 0;
145 int64_t m_laps = 0;
146 utility::bit_flags<6> m_config = {};
147 std::shared_ptr<base::ring_buffer> m_buffer = { nullptr };
148
149protected:
150 // protected member function section
151 enum ConfigIdx
152 {
153 EnabledIdx = 0, // enabled
154 StoreIdx = 1, // push/pop
155 ExPushIdx = 2, // explicit push
156 ExPopIdx = 3, // explicit pop
157 PushedIdx = 4, // was pushed
158 ActiveIdx = 5, // running
159 };
160
161 TIMEMORY_INLINE bool m_enabled() const { return m_config.test<EnabledIdx>(); }
162 TIMEMORY_INLINE bool m_store() const { return m_config.test<StoreIdx>(); }
163 TIMEMORY_INLINE bool m_explicit_push() const { return m_config.test<ExPushIdx>(); }
164 TIMEMORY_INLINE bool m_explicit_pop() const { return m_config.test<ExPopIdx>(); }
165 TIMEMORY_INLINE bool m_is_pushed() const { return m_config.test<PushedIdx>(); }
166 TIMEMORY_INLINE bool m_is_active() const { return m_config.test<ActiveIdx>(); }
167
168 TIMEMORY_INLINE void m_enabled(bool v) { m_config.set<EnabledIdx>(v); }
169 TIMEMORY_INLINE void m_store(bool v) { m_config.set<StoreIdx>(v); }
170 TIMEMORY_INLINE void m_explicit_push(bool v) { return m_config.set<ExPushIdx>(v); }
171 TIMEMORY_INLINE void m_explicit_pop(bool v) { return m_config.set<ExPopIdx>(v); }
172 TIMEMORY_INLINE void m_is_pushed(bool v) { m_config.set<PushedIdx>(v); }
173 TIMEMORY_INLINE void m_is_active(bool v) { m_config.set<ActiveIdx>(v); }
174};
175//
176template <typename... Types>
177class base_bundle;
178//
179/// \class tim::impl::base_bundle<typename Tag, typename... Types>
180/// \brief This is the generic structure for a variadic bundle of components
181///
182template <typename Tag, typename... Types>
183class base_bundle<Tag, Types...>
184: public common_base_bundle
185, public concepts::variadic
186, public concepts::wrapper
187{
188public:
189 using tag_type = Tag;
190 using impl_type = std::tuple<Types...>;
191 using sample_type = typename tim::variadic::impl::bundle<impl_type>::sample_type;
192 using tuple_type = typename tim::variadic::impl::bundle<impl_type>::tuple_type;
193 using reference_type =
194 typename tim::variadic::impl::bundle<impl_type>::reference_type;
195 using print_type = typename tim::variadic::impl::bundle<impl_type>::print_type;
197 using user_bundle_types =
199
200 template <template <typename> class Op, typename... T>
201 using generic_operation = tim::variadic::impl::generic_operation<Op, tag_type, T...>;
202
203 template <template <typename> class Op, typename... T>
204 using custom_operation = tim::variadic::impl::custom_operation<Op, T...>;
205
206 template <template <typename> class Op, typename TupleT = tuple_type>
207 using operation_t = typename generic_operation<Op, TupleT>::type;
208
209 template <template <typename> class Op, typename TupleT = tuple_type>
210 using custom_operation_t =
211 typename tim::variadic::impl::custom_operation<Op, TupleT>::type;
212
213 template <typename U>
214 using sample_type_t = tim::variadic::impl::sample_type_t<U>;
215
216public:
217 // public static function section
218 static constexpr bool empty() { return (size() == 0); }
219 static constexpr size_t size() { return sizeof...(Types); }
220
221 template <typename... T>
222 static auto get_scope_config()
223 {
224 return scope::config{ quirk_config<quirk::flat_scope, T...>::value,
225 quirk_config<quirk::timeline_scope, T...>::value,
226 quirk_config<quirk::tree_scope, T...>::value };
227 }
228
229 template <typename... T>
230 static auto get_store_config()
231 {
232 return !quirk_config<quirk::no_store, T...>::value;
233 }
234
235public:
236 // public static data section
237 static constexpr bool has_gotcha_v = (mpl::get_tuple_size<gotcha_types>::value != 0);
238 static constexpr bool has_user_bundle_v =
240
241public:
242 base_bundle& operator+=(const base_bundle& rhs)
243 {
245 return *this;
246 }
247
248 base_bundle& operator-=(const base_bundle& rhs)
249 {
251 return *this;
252 }
253
254protected:
255 using ctor_params_t = std::tuple<hash_value_t, bool, scope::config>;
256
257 // protected construction / destruction section
258 template <typename U = impl_type>
259 base_bundle(ctor_params_t _params = ctor_params_t(
260 0, tim::variadic::impl::global_enabled(), scope::get_default()),
261 enable_if_t<std::tuple_size<U>::value != 0, int> = 0)
262 : common_base_bundle{ std::get<2>(_params) + get_scope_config(),
263 std::get<0>(_params) }
264 {
266 m_store(m_enabled() && std::get<1>(_params) && get_store_config());
267 }
268
269 template <typename U = impl_type>
270 base_bundle(ctor_params_t = ctor_params_t(),
271 enable_if_t<std::tuple_size<U>::value == 0, int> = 0)
272 {}
273
274 ~base_bundle() = default;
275 base_bundle(const base_bundle&) = default;
276 base_bundle(base_bundle&&) = default;
277 base_bundle& operator=(const base_bundle&) = default;
278 base_bundle& operator=(base_bundle&&) = default;
279
280public:
281 void rekey(const string_t& _key)
282 {
283 m_hash = add_hash_id(_key);
284 compute_width(_key);
285 }
286
287protected:
288 void compute_width(const string_t& _key) const
289 {
290 output_width(_key.length() + get_prefix().length() + 1);
291 }
292
293 void update_width() const { compute_width(key()); }
294
295 const auto& prefix() const { return get_persistent_data().prefix; }
296 const auto& get_prefix() const { return prefix(); }
297
298 using common_base_bundle::m_buffer;
299 using common_base_bundle::m_config;
300 using common_base_bundle::m_hash;
301 using common_base_bundle::m_laps;
302 using common_base_bundle::m_scope;
303
304 bool init_buffer()
305 {
306 if(m_buffer.get() == nullptr)
307 {
308 static auto _size = []() {
309 size_t _v = 0;
310 TIMEMORY_FOLD_EXPRESSION(_v += mpl::dynamic_buffer_size<Types>{}());
311 return _v;
312 }();
313 if(_size > 0)
314 m_buffer = std::make_shared<base::ring_buffer>(_size, false);
315 return m_buffer != nullptr;
316 }
317 return m_buffer->is_full();
318 }
319
320protected:
321 // protected static function section
322 static int64_t output_width(int64_t width = 0)
323 {
324 return get_persistent_data().get_width(width);
325 }
326
327protected:
328 // protected static function section [HANDLERS]
329 template <typename... T>
330 static hash_value_t handle_key(type_list<T...>, hash_value_t _hash)
331 {
332 return _hash;
333 }
334
335 // HAS SIZE
336 template <typename... T>
337 static hash_value_t handle_key(type_list<T...>, const string_t& _key,
338 enable_if_t<sizeof...(T) != 0, int> = {})
339 {
340 return (tim::variadic::impl::global_enabled()) ? add_hash_id(_key) : 0;
341 }
342
343 template <typename... T>
344 static hash_value_t handle_key(type_list<T...>, const captured_location_t& _loc,
345 enable_if_t<sizeof...(T) != 0, int> = {})
346 {
347 return _loc.get_hash();
348 }
349
350 template <typename... T, typename... U>
351 static scope::config handle_scope(type_list<T...>, scope::config _scope,
352 quirk::config<U...>,
353 enable_if_t<sizeof...(T) != 0, int> = {})
354 {
355 return _scope + get_scope_config<T..., U...>();
356 }
357
358 template <typename... T, typename... U>
359 static scope::config handle_scope(type_list<T...>, quirk::config<U...>,
360 enable_if_t<sizeof...(T) != 0, int> = {})
361 {
362 return scope::get_default() + get_scope_config<T..., U...>();
363 }
364
365 template <typename... T, typename... U>
366 static bool handle_store(type_list<T...>, bool _enable, quirk::config<U...>,
367 enable_if_t<sizeof...(T) != 0, int> = {})
368 {
369 return get_store_config<T..., U...>() && _enable &&
370 tim::variadic::impl::global_enabled();
371 }
372
373 template <typename... T, typename... U>
374 static bool handle_store(type_list<T...>, std::true_type, quirk::config<U...>,
375 enable_if_t<sizeof...(T) != 0, int> = {})
376 {
377 return get_store_config<T..., U...>() && tim::variadic::impl::global_enabled();
378 }
379
380 template <typename... T, typename... U>
381 static bool handle_store(type_list<T...>, std::false_type, quirk::config<U...>,
382 enable_if_t<sizeof...(T) != 0, int> = {})
383 {
384 return get_store_config<T..., U...>();
385 }
386
387 // ZERO SIZE
388 template <typename... T>
389 static hash_value_t handle_key(type_list<T...>, const string_t&,
390 enable_if_t<sizeof...(T) == 0, int> = {})
391 {
392 return 0;
393 }
394
395 template <typename... T>
396 static hash_value_t handle_key(type_list<T...>, const captured_location_t&,
397 enable_if_t<sizeof...(T) == 0, int> = {})
398 {
399 return 0;
400 }
401
402 template <typename... T, typename... U>
403 static auto handle_scope(type_list<T...>, scope::config, quirk::config<U...>,
404 enable_if_t<sizeof...(T) == 0, int> = {})
405 {
406 return scope::config{};
407 }
408
409 template <typename... T, typename... U>
410 static auto handle_scope(type_list<T...>, quirk::config<U...>,
411 enable_if_t<sizeof...(T) == 0, int> = {})
412 {
413 return scope::config{};
414 }
415
416 template <typename... T, typename... U>
417 static bool handle_store(type_list<T...>, bool, quirk::config<U...>,
418 enable_if_t<sizeof...(T) == 0, int> = {})
419 {
420 return false;
421 }
422
423 template <typename... T, typename... U>
424 static bool handle_store(type_list<T...>, std::true_type, quirk::config<U...>,
425 enable_if_t<sizeof...(T) == 0, int> = {})
426 {
427 return false;
428 }
429
430 template <typename... T, typename... U>
431 static bool handle_store(type_list<T...>, std::false_type, quirk::config<U...>,
432 enable_if_t<sizeof...(T) == 0, int> = {})
433 {
434 return false;
435 }
436
437 // GENERIC HANDLERS
438 template <typename... T, typename KeyT, typename StoreT, typename ScopeT,
439 typename QuirkT>
440 static auto handle(type_list<T...> _types, KeyT&& _key, StoreT&& _store,
441 ScopeT&& _scope, QuirkT&& _quirk)
442 {
443 return ctor_params_t{ handle_key(_types, std::forward<KeyT>(_key)),
444 handle_store(_types, std::forward<StoreT>(_store),
445 std::forward<QuirkT>(_quirk)),
446 handle_scope(_types, std::forward<ScopeT>(_scope),
447 std::forward<QuirkT>(_quirk)) };
448 }
449
450 template <typename... T, typename KeyT, typename StoreT>
451 static auto handle(type_list<T...> _types, KeyT&& _key, StoreT&& _store,
452 scope::config _scope)
453 {
454 return handle(_types, std::forward<KeyT>(_key), std::forward<StoreT>(_store),
455 _scope, quirk::config<>{});
456 }
457
458 template <typename... T, typename KeyT, typename StoreT, typename... U>
459 static auto handle(type_list<T...> _types, KeyT&& _key, StoreT&& _store,
460 quirk::config<U...> _quirk)
461 {
462 return ctor_params_t{ handle_key(_types, std::forward<KeyT>(_key)),
463 handle_store(_types, std::forward<StoreT>(_store), _quirk),
464 handle_scope(_types, _quirk) };
465 }
466
467 template <typename... T, typename Tp, typename TupleT, typename FuncT, typename... U>
468 static void init(type_list<T...>, Tp& _this, TupleT&& _data, FuncT&& _init,
469 quirk::config<U...> = quirk::config<>{},
470 enable_if_t<sizeof...(T) != 0, int> = {})
471 {
472 if(tim::variadic::impl::global_enabled())
473 {
474 IF_CONSTEXPR(!quirk_config<quirk::no_init, T..., U...>::value)
475 {
476 _init(_this);
477 }
478 _this.m_explicit_push(quirk_config<quirk::explicit_push, T..., U...>::value);
479 _this.m_explicit_pop(quirk_config<quirk::explicit_pop, T..., U...>::value);
480 _this.set_prefix(_this.get_hash());
481 invoke::set_scope(_data, _this.get_scope());
482 IF_CONSTEXPR(quirk_config<quirk::auto_start, T..., U...>::value)
483 {
484 _this.start();
485 }
486 }
487 }
488
489 template <typename... T, typename Tp, typename TupleT, typename FuncT, typename... U>
490 static void init(type_list<T...>, Tp&, TupleT&&, FuncT&&,
491 quirk::config<U...> = quirk::config<>{},
492 enable_if_t<sizeof...(T) == 0, int> = {})
493 {}
494
495private:
496 // private alias section
497 template <typename T, typename... U>
498 using quirk_config = tim::variadic::impl::quirk_config<T, type_list<Types...>, U...>;
499
500 // private static data section
501 struct persistent_data
502 {
503 int64_t get_width(int64_t _w)
504 {
505 IF_CONSTEXPR(!empty())
506 {
507 auto&& memorder_v = std::memory_order_relaxed;
508 int64_t propose_width;
509 int64_t current_width;
510 auto compute = [&]() { return std::max(width.load(memorder_v), _w); };
511 while((propose_width = compute()) >
512 (current_width = width.load(memorder_v)))
513 {
514 width.compare_exchange_strong(current_width, propose_width,
515 memorder_v);
516 }
517 return width.load(memorder_v);
518 }
519 (void) _w; // unused parameter warning when 'if constexpr' available
520 return 0;
521 }
522
523 std::atomic<int64_t> width{ 0 };
524 std::string prefix = []() -> std::string {
525 IF_CONSTEXPR(!empty())
526 {
527 if(!dmp::is_initialized())
528 return std::string(">>> ");
529
530 // prefix spacing
531 static uint16_t _width = 1;
532 if(dmp::size() > 9)
533 _width = std::max(_width, (uint16_t)(log10(dmp::size()) + 1));
534 std::stringstream ss;
535 ss.fill('0');
536 ss << "|" << std::setw(_width) << dmp::rank() << ">>> ";
537 return ss.str();
538 }
539 else { return std::string{}; }
540 }();
541 };
542
543 static persistent_data& get_persistent_data()
544 {
545 static persistent_data _instance{};
546 return _instance;
547 }
548};
549//
550//======================================================================================//
551//
552template <typename Tag, typename... Types>
553class base_bundle<Tag, std::tuple<Types...>> : public base_bundle<Tag, Types...>
554{
555public:
556 using data_type =
558 std::tuple<>>;
559
560 template <typename... Args>
561 base_bundle(Args&&... args)
562 : base_bundle<Tag, Types...>(std::forward<Args>(args)...)
563 {}
564};
565
566template <typename Tag, typename... Types>
567class base_bundle<Tag, type_list<Types...>> : public base_bundle<Tag, Types...>
568{
569public:
570 using data_type =
572 std::tuple<>>;
573
574 template <typename... Args>
575 base_bundle(Args&&... args)
576 : base_bundle<Tag, Types...>(std::forward<Args>(args)...)
577 {}
578};
579//
580} // namespace impl
581//
582//======================================================================================//
583//
584template <typename... Types>
586: public impl::base_bundle<TIMEMORY_API, Types...>
588{
589 using data_type =
591 std::tuple<>>;
592
593 template <typename... Args>
594 stack_bundle(Args&&... args)
595 : impl::base_bundle<TIMEMORY_API, Types...>(std::forward<Args>(args)...)
596 {}
597};
598
599template <typename... Types>
600struct stack_bundle<std::tuple<Types...>>
601: public impl::base_bundle<TIMEMORY_API, Types...>
602, public concepts::stack_wrapper
603{
604 using data_type =
606 std::tuple<>>;
607
608 template <typename... Args>
609 stack_bundle(Args&&... args)
610 : impl::base_bundle<TIMEMORY_API, Types...>(std::forward<Args>(args)...)
611 {}
612};
613
614template <typename... Types>
615struct stack_bundle<type_list<Types...>>
616: public impl::base_bundle<TIMEMORY_API, Types...>
618{
619 using data_type =
621 std::tuple<>>;
622
623 template <typename... Args>
624 stack_bundle(Args&&... args)
625 : impl::base_bundle<TIMEMORY_API, Types...>(std::forward<Args>(args)...)
626 {}
627};
628//
629//======================================================================================//
630//
631template <typename ApiT, typename... Types>
633: public conditional_t<trait::is_available<ApiT>::value,
634 impl::base_bundle<ApiT, remove_pointer_t<Types>...>,
635 impl::base_bundle<ApiT, std::tuple<>>>
636, public concepts::tagged
638{
639 static_assert(concepts::is_api<ApiT>::value,
640 "Error! The first template parameter of an 'api_bundle' must "
641 "statisfy the 'is_api' concept");
642
645 impl::base_bundle<ApiT, remove_pointer_t<Types>...>,
646 impl::base_bundle<ApiT, std::tuple<>>>;
647 using data_type =
649 mpl::non_placeholder_t<mpl::non_quirk_t<std::tuple<Types...>>>,
650 std::tuple<>>;
653
654 template <typename... Args>
655 api_bundle(Args&&... args)
656 : base_bundle_type(std::forward<Args>(args)...)
657 {}
658};
659
660template <typename ApiT, typename... Types>
661struct api_bundle<ApiT, std::tuple<Types...>>
662: public conditional_t<trait::is_available<ApiT>::value,
663 impl::base_bundle<ApiT, remove_pointer_t<Types>...>,
664 impl::base_bundle<ApiT, std::tuple<>>>
665, public concepts::tagged
666, public concepts::comp_wrapper
667{
668 static_assert(concepts::is_api<ApiT>::value,
669 "Error! The first template parameter of an 'api_bundle' must "
670 "statisfy the 'is_api' concept");
671
672 using base_bundle_type =
673 conditional_t<trait::is_available<ApiT>::value,
674 impl::base_bundle<ApiT, remove_pointer_t<Types>...>,
675 impl::base_bundle<ApiT, std::tuple<>>>;
676 using data_type =
677 conditional_t<trait::is_available<ApiT>::value,
678 mpl::non_placeholder_t<mpl::non_quirk_t<std::tuple<Types...>>>,
679 std::tuple<>>;
680 using tuple_type = data_type;
681 using impl_type = data_type;
682
683 template <typename... Args>
684 api_bundle(Args&&... args)
685 : base_bundle_type(std::forward<Args>(args)...)
686 {}
687
688 api_bundle& operator+=(const api_bundle& rhs)
689 {
691 return *this;
692 }
693
694 api_bundle& operator-=(const api_bundle& rhs)
695 {
697 return *this;
698 }
699
700protected:
701 using base_bundle_type::init_buffer;
702 using base_bundle_type::m_buffer;
703 using base_bundle_type::m_config;
704 using base_bundle_type::m_hash;
705 using base_bundle_type::m_laps;
706 using base_bundle_type::m_scope;
707};
708
709template <typename ApiT, typename... Types>
710struct api_bundle<ApiT, type_list<Types...>>
711: public conditional_t<trait::is_available<ApiT>::value,
712 impl::base_bundle<ApiT, remove_pointer_t<Types>...>,
713 impl::base_bundle<ApiT, std::tuple<>>>
714, public concepts::tagged
716{
717 static_assert(concepts::is_api<ApiT>::value,
718 "Error! The first template parameter of an 'api_bundle' must "
719 "statisfy the 'is_api' concept");
720
723 impl::base_bundle<ApiT, remove_pointer_t<Types>...>,
724 impl::base_bundle<ApiT, std::tuple<>>>;
725 using data_type =
727 mpl::non_placeholder_t<mpl::non_quirk_t<std::tuple<Types...>>>,
728 std::tuple<>>;
729 using type_list_type = type_list<Types...>;
732
733 template <typename... Args>
734 api_bundle(Args&&... args)
735 : base_bundle_type(std::forward<Args>(args)...)
736 {}
737
739 {
741 return *this;
742 }
743
745 {
747 return *this;
748 }
749
750protected:
751 using base_bundle_type::init_buffer;
752 using base_bundle_type::m_buffer;
753 using base_bundle_type::m_config;
754 using base_bundle_type::m_hash;
755 using base_bundle_type::m_laps;
756 using base_bundle_type::m_scope;
757};
758//
759//======================================================================================//
760//
761} // namespace tim
#define IF_CONSTEXPR(...)
Definition: language.hpp:72
std::string string_t
Definition: library.cpp:57
STL namespace.
::tim::statistics< Tp > max(::tim::statistics< Tp > lhs, const Tp &rhs)
Definition: statistics.hpp:320
::tim::statistics< tuple<> > & operator+=(::tim::statistics< tuple<> > &_lhs, const Tp &)
Definition: statistics.hpp:338
hash_value_t add_hash_id(hash_map_ptr_t &_hash_map, string_view_cref_t _prefix)
add an string to the given hash-map (if it doesn't already exist) and return the hash
Definition: types.hpp:190
bool get_hash_identifier(const hash_map_ptr_t &_hash_map, const hash_alias_ptr_t &_hash_alias, hash_value_t _hash_id, std::string *&_ret)
size_t get_hash(T &&obj)
Definition: utility.hpp:206
size_t hash_value_t
Definition: types.hpp:84
void set_scope(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:810
void store(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:564
impl::filter_false< Predicate, std::tuple< Sequence... > > type
Definition: available.hpp:259
impl::filter_true< concepts::is_quirk_type, T > non_quirk_t
Definition: available.hpp:310
impl::filter_true< concepts::is_placeholder, T > non_placeholder_t
Definition: available.hpp:313
std::bitset< scope_count > data_type
Definition: types.hpp:399
std::array< Tp, N > & operator+=(std::array< Tp, N > &, Other &&)
std::array< Tp, N > & operator-=(std::array< Tp, N > &, const std::array< Tp, N > &)
Definition: stl.hpp:96
Definition: kokkosp.cpp:39
std::string string_view_t
Definition: language.hpp:102
typename std::enable_if< B, T >::type enable_if_t
Alias template for enable_if.
Definition: types.hpp:190
void init(Args &&... args)
Definition: types.hpp:111
tim::mpl::apply< std::string > string
Definition: macros.hpp:53
auto get(const auto_bundle< Tag, Types... > &_obj)
typename std::conditional< B, Lhs, Rhs >::type conditional_t
Definition: types.hpp:197
typename impl::convert< T, U >::type convert_t
Definition: types.hpp:855
lightweight tuple-alternative for meta-programming logic
Definition: types.hpp:233
Declare the operations types.
conditional_t< trait::is_available< ApiT >::value, impl::base_bundle< ApiT, remove_pointer_t< Types >... >, impl::base_bundle< ApiT, std::tuple<> > > base_bundle_type
conditional_t< trait::is_available< ApiT >::value, mpl::non_placeholder_t< mpl::non_quirk_t< std::tuple< Types... > > >, std::tuple<> > data_type
api_bundle & operator-=(const api_bundle &rhs)
api_bundle & operator+=(const api_bundle &rhs)
api_bundle(Args &&... args)
data_type tuple_type
data_type impl_type
conditional_t< trait::is_available< ApiT >::value, mpl::non_placeholder_t< mpl::non_quirk_t< std::tuple< Types... > > >, std::tuple<> > data_type
conditional_t< trait::is_available< ApiT >::value, impl::base_bundle< ApiT, remove_pointer_t< Types >... >, impl::base_bundle< ApiT, std::tuple<> > > base_bundle_type
concept that specifies that a type is an API. APIs are used to designate different project implementa...
Definition: concepts.hpp:273
static constexpr bool value
Definition: concepts.hpp:273
static constexpr size_t value
Definition: types.hpp:922
This operation class is similar to pointer_operator but can handle non-pointer types.
Definition: generic.hpp:55
convert_t< mpl::non_placeholder_t< mpl::non_quirk_t< type_list< Types... > > >, std::tuple<> > data_type
convert_t< mpl::non_placeholder_t< mpl::non_quirk_t< type_list< Types... > > >, std::tuple<> > data_type
stack_bundle(Args &&... args)
static bool get(enable_if_t< is_available< U >::value &&get_value< U >(), int >=0)
GET specialization if component is available.
#define TIMEMORY_FOLD_EXPRESSION(...)
Definition: types.hpp:56
type_list
Definition: types.hpp:211