timemory  3.2.1
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.
bundle.cpp
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 #ifndef TIMEMORY_VARIADIC_BUNDLE_CPP_
26 #define TIMEMORY_VARIADIC_BUNDLE_CPP_
27 
29 #include "timemory/backends/dmp.hpp"
30 #include "timemory/mpl/filters.hpp"
33 #include "timemory/tpls/cereal/cereal.hpp"
38 
39 namespace tim
40 {
41 //--------------------------------------------------------------------------------------//
42 //
43 template <typename Tag, typename BundleT, typename TupleT>
46 {
47  static initializer_type _instance = [](this_type&) {};
48  return _instance;
49 }
50 
51 //--------------------------------------------------------------------------------------//
52 //
53 template <typename Tag, typename BundleT, typename TupleT>
55 {
56  update_last_instance(&get_this_type(), get_last_instance(),
58  IF_CONSTEXPR(optional_count() > 0) { apply_v::set_value(m_data, nullptr); }
59  bundle_type::init(type_list_type{}, get_this_type(), m_data, get_initializer());
60 }
61 
62 //--------------------------------------------------------------------------------------//
63 //
64 template <typename Tag, typename BundleT, typename TupleT>
65 template <typename... T>
67  transient_func_t _init_func)
68 : bundle_type(bundle_type::handle(type_list_type{}, _key, true_type{}, _config))
69 , m_data(invoke::construct<data_type, Tag>(_key, _config))
70 {
71  update_last_instance(&get_this_type(), get_last_instance(),
73  IF_CONSTEXPR(optional_count() > 0) { apply_v::set_value(m_data, nullptr); }
74  bundle_type::init(type_list_type{}, get_this_type(), m_data, std::move(_init_func),
75  _config);
76 }
77 
78 //--------------------------------------------------------------------------------------//
79 //
80 template <typename Tag, typename BundleT, typename TupleT>
81 template <typename... T>
83  transient_func_t _init_func)
84 : bundle_type(bundle_type::handle(type_list_type{}, _hash, true_type{}, _config))
85 , m_data(invoke::construct<data_type, Tag>(_hash, _config))
86 {
87  update_last_instance(&get_this_type(), get_last_instance(),
89  IF_CONSTEXPR(optional_count() > 0) { apply_v::set_value(m_data, nullptr); }
90  bundle_type::init(type_list_type{}, get_this_type(), m_data, std::move(_init_func),
91  _config);
92 }
93 
94 //--------------------------------------------------------------------------------------//
95 //
96 template <typename Tag, typename BundleT, typename TupleT>
97 template <typename... T>
99  quirk::config<T...> _config,
100  transient_func_t _init_func)
101 : bundle_type(bundle_type::handle(type_list_type{}, _loc, true_type{}, _config))
102 , m_data(invoke::construct<data_type, Tag>(_loc, _config))
103 {
104  update_last_instance(&get_this_type(), get_last_instance(),
106  IF_CONSTEXPR(optional_count() > 0) { apply_v::set_value(m_data, nullptr); }
107  bundle_type::init(type_list_type{}, get_this_type(), m_data, std::move(_init_func),
108  _config);
109 }
110 
111 //--------------------------------------------------------------------------------------//
112 //
113 template <typename Tag, typename BundleT, typename TupleT>
114 template <typename... T>
116  quirk::config<T...> _config,
117  transient_func_t _init_func)
118 : bundle_type(bundle_type::handle(type_list_type{}, _key, _store, _config))
119 , m_data(invoke::construct<data_type, Tag>(_key, _config))
120 {
121  update_last_instance(&get_this_type(), get_last_instance(),
123  IF_CONSTEXPR(optional_count() > 0) { apply_v::set_value(m_data, nullptr); }
124  bundle_type::init(type_list_type{}, get_this_type(), m_data, std::move(_init_func),
125  _config);
126 }
127 
128 //--------------------------------------------------------------------------------------//
129 //
130 template <typename Tag, typename BundleT, typename TupleT>
131 template <typename... T>
133  quirk::config<T...> _config,
134  transient_func_t _init_func)
135 : bundle_type(bundle_type::handle(type_list_type{}, _loc, _store, _config))
136 , m_data(invoke::construct<data_type, Tag>(_loc, _config))
137 {
138  update_last_instance(&get_this_type(), get_last_instance(),
140  IF_CONSTEXPR(optional_count() > 0) { apply_v::set_value(m_data, nullptr); }
141  bundle_type::init(type_list_type{}, get_this_type(), m_data, std::move(_init_func),
142  _config);
143 }
144 
145 //--------------------------------------------------------------------------------------//
146 //
147 template <typename Tag, typename BundleT, typename TupleT>
149  scope::config _scope, transient_func_t _init_func)
150 : bundle_type(bundle_type::handle(type_list_type{}, _hash, _store, _scope))
151 , m_data(invoke::construct<data_type, Tag>(_hash, m_scope))
152 {
153  update_last_instance(&get_this_type(), get_last_instance(),
155  IF_CONSTEXPR(optional_count() > 0) { apply_v::set_value(m_data, nullptr); }
156  bundle_type::init(type_list_type{}, get_this_type(), m_data, std::move(_init_func));
157 }
158 
159 //--------------------------------------------------------------------------------------//
160 //
161 template <typename Tag, typename BundleT, typename TupleT>
163  scope::config _scope, transient_func_t _init_func)
164 : bundle_type(bundle_type::handle(type_list_type{}, _key, _store, _scope))
165 {
166  update_last_instance(&get_this_type(), get_last_instance(),
168  IF_CONSTEXPR(optional_count() > 0) { apply_v::set_value(m_data, nullptr); }
169  bundle_type::init(type_list_type{}, get_this_type(), m_data, std::move(_init_func));
170 }
171 
172 //--------------------------------------------------------------------------------------//
173 //
174 template <typename Tag, typename BundleT, typename TupleT>
176  scope::config _scope, transient_func_t _init_func)
177 : bundle_type(bundle_type::handle(type_list_type{}, _loc, _store, _scope))
178 {
179  update_last_instance(&get_this_type(), get_last_instance(),
181  IF_CONSTEXPR(optional_count() > 0) { apply_v::set_value(m_data, nullptr); }
182  bundle_type::init(type_list_type{}, get_this_type(), m_data, std::move(_init_func));
183 }
184 
185 //--------------------------------------------------------------------------------------//
186 //
187 template <typename Tag, typename BundleT, typename TupleT>
189  transient_func_t _init_func)
190 : bundle_type(bundle_type::handle(type_list_type{}, _hash, true_type{}, _scope))
191 {
192  update_last_instance(&get_this_type(), get_last_instance(),
194  IF_CONSTEXPR(optional_count() > 0) { apply_v::set_value(m_data, nullptr); }
195  bundle_type::init(type_list_type{}, get_this_type(), m_data, std::move(_init_func));
196 }
197 
198 //--------------------------------------------------------------------------------------//
199 //
200 template <typename Tag, typename BundleT, typename TupleT>
202  transient_func_t _init_func)
203 : bundle_type(bundle_type::handle(type_list_type{}, _key, true_type{}, _scope))
204 {
205  update_last_instance(&get_this_type(), get_last_instance(),
207  IF_CONSTEXPR(optional_count() > 0) { apply_v::set_value(m_data, nullptr); }
208  bundle_type::init(type_list_type{}, get_this_type(), m_data, std::move(_init_func));
209 }
210 
211 //--------------------------------------------------------------------------------------//
212 //
213 template <typename Tag, typename BundleT, typename TupleT>
215  scope::config _scope, transient_func_t _init_func)
216 : bundle_type(bundle_type::handle(type_list_type{}, _loc, true_type{}, _scope))
217 {
218  update_last_instance(&get_this_type(), get_last_instance(),
220  IF_CONSTEXPR(optional_count() > 0) { apply_v::set_value(m_data, nullptr); }
221  bundle_type::init(type_list_type{}, get_this_type(), m_data, std::move(_init_func));
222 }
223 
224 //--------------------------------------------------------------------------------------//
225 //
226 template <typename Tag, typename BundleT, typename TupleT>
228 {
229  if(get_last_instance() == &get_this_type())
230  update_last_instance(nullptr, get_last_instance(), false);
231 
233  {
234  if(m_is_active())
235  stop();
236  }
237 
238  IF_CONSTEXPR(optional_count() > 0)
239  {
240 #if defined(DEBUG) && !defined(NDEBUG)
242  {
243  PRINT_HERE("%s", "deleting components");
244  }
245 #endif
246  invoke::destroy<Tag>(m_data);
247  }
248 }
249 
250 //--------------------------------------------------------------------------------------//
251 //
252 template <typename Tag, typename BundleT, typename TupleT>
254 : bundle_type(rhs)
255 {
257  IF_CONSTEXPR(optional_count() > 0) { apply_v::set_value(m_data, nullptr); }
258  apply_v::access2<copy_oper_t>(m_data, rhs.m_data);
259 }
260 
261 //--------------------------------------------------------------------------------------//
262 //
263 template <typename Tag, typename BundleT, typename TupleT>
266 {
267  if(this != &rhs)
268  {
269  bundle_type::operator=(rhs);
270  invoke::destroy<Tag>(m_data);
271  invoke::invoke_impl::invoke_data<operation::copy, Tag>(m_data, rhs.m_data);
272  // apply_v::access<operation_t<operation::copy>>(m_data);
273  }
274  return get_this_type();
275 }
276 
277 //--------------------------------------------------------------------------------------//
278 // this_type operators
279 //
280 template <typename Tag, typename BundleT, typename TupleT>
283 {
284  bundle_type::operator-=(static_cast<const bundle_type&>(rhs));
285  invoke::invoke_impl::invoke_data<operation::minus, Tag>(m_data, rhs.m_data);
286  return get_this_type();
287 }
288 
289 //--------------------------------------------------------------------------------------//
290 //
291 template <typename Tag, typename BundleT, typename TupleT>
294 {
295  bundle_type::operator+=(static_cast<const bundle_type&>(rhs));
296  invoke::invoke_impl::invoke_data<operation::plus, Tag>(m_data, rhs.m_data);
297  return get_this_type();
298 }
299 
300 //--------------------------------------------------------------------------------------//
301 //
302 template <typename Tag, typename BundleT, typename TupleT>
305 {
306  bundle tmp(*this);
307  tmp.m_store(_store);
308  tmp.m_scope = _scope;
309  return tmp;
310 }
311 
312 //--------------------------------------------------------------------------------------//
313 //
314 template <typename Tag, typename BundleT, typename TupleT>
315 void
317 {
318  static thread_local bool _once = []() {
319  apply_v::type_access<operation::init_storage, mpl::non_quirk_t<reference_type>>();
320  return true;
321  }();
322  consume_parameters(_once);
323 }
324 
325 //--------------------------------------------------------------------------------------//
326 // insert into graph
327 //
328 template <typename Tag, typename BundleT, typename TupleT>
331 {
332  if(!m_enabled())
333  return get_this_type();
334 
335  if(!m_is_pushed())
336  {
337  // reset the data
338  invoke::reset<Tag>(m_data);
339  // avoid pushing/popping when already pushed/popped
340  m_is_pushed(true);
341  // insert node or find existing node
342  invoke::push<Tag>(m_data, m_scope, m_hash);
343  }
344  return get_this_type();
345 }
346 
347 //--------------------------------------------------------------------------------------//
348 // insert into graph
349 //
350 template <typename Tag, typename BundleT, typename TupleT>
351 template <typename... Tp>
354 {
355  if(!m_enabled())
356  return get_this_type();
357 
358  using pw_type = convert_t<mpl::implemented_t<Tp...>, mpl::piecewise_select<>>;
359  // reset the data
360  invoke::invoke<operation::reset, Tag>(pw_type{}, m_data);
361  // insert node or find existing node
362  invoke::invoke<operation::push_node, Tag>(pw_type{}, m_data, m_scope, m_hash);
363  return get_this_type();
364 }
365 
366 //--------------------------------------------------------------------------------------//
367 // insert into graph
368 //
369 template <typename Tag, typename BundleT, typename TupleT>
370 template <typename... Tp>
373 {
374  if(!m_enabled())
375  return get_this_type();
376 
377  using pw_type = convert_t<mpl::implemented_t<Tp...>, mpl::piecewise_select<>>;
378  // reset the data
379  invoke::invoke<operation::reset, Tag>(pw_type{}, m_data);
380  // insert node or find existing node
381  invoke::invoke<operation::push_node, Tag>(pw_type{}, m_data, _scope, m_hash);
382  return get_this_type();
383 }
384 
385 //--------------------------------------------------------------------------------------//
386 // pop out of graph
387 //
388 template <typename Tag, typename BundleT, typename TupleT>
391 {
392  if(!m_enabled())
393  return get_this_type();
394 
395  if(m_is_pushed())
396  {
397  // set the current node to the parent node
398  invoke::pop<Tag>(m_data);
399  // avoid pushing/popping when already pushed/popped
400  m_is_pushed(false);
401  }
402  return get_this_type();
403 }
404 
405 //--------------------------------------------------------------------------------------//
406 // pop out of graph
407 //
408 template <typename Tag, typename BundleT, typename TupleT>
409 template <typename... Tp>
412 {
413  if(!m_enabled())
414  return get_this_type();
415 
416  using pw_type = convert_t<mpl::implemented_t<Tp...>, mpl::piecewise_select<>>;
417  // set the current node to the parent node
418  invoke::invoke<operation::pop_node, Tag>(pw_type{}, m_data);
419  return get_this_type();
420 }
421 
422 //--------------------------------------------------------------------------------------//
423 // measure functions
424 //
425 template <typename Tag, typename BundleT, typename TupleT>
426 template <typename... Args>
429 {
430  return invoke<operation::measure>(std::forward<Args>(args)...);
431 }
432 
433 //--------------------------------------------------------------------------------------//
434 // sample functions
435 //
436 template <typename Tag, typename BundleT, typename TupleT>
437 template <typename... Args>
440 {
441  return invoke<operation::sample>(std::forward<Args>(args)...);
442 }
443 
444 //--------------------------------------------------------------------------------------//
445 // start/stop functions with no push/pop or assemble/derive
446 //
447 template <typename Tag, typename BundleT, typename TupleT>
448 template <typename... Args>
451 {
452  if(!m_enabled())
453  return get_this_type();
454 
455  assemble(*this);
456  invoke::start<Tag>(m_data, std::forward<Args>(args)...);
457  m_is_active(true);
458  return get_this_type();
459 }
460 
461 //--------------------------------------------------------------------------------------//
462 //
463 template <typename Tag, typename BundleT, typename TupleT>
464 template <typename... Args>
467 {
468  if(!m_enabled())
469  return get_this_type();
470 
471  invoke::stop<Tag>(m_data, std::forward<Args>(args)...);
472  if(m_is_active())
473  ++m_laps;
474  derive(*this);
475  m_is_active(false);
476  return get_this_type();
477 }
478 
479 //--------------------------------------------------------------------------------------//
480 // start/stop functions with no push/pop or assemble/derive
481 //
482 template <typename Tag, typename BundleT, typename TupleT>
483 template <typename... Tp, typename... Args>
486 {
487  if(!m_enabled())
488  return get_this_type();
489 
490  using select_tuple_t = mpl::sort<trait::start_priority, std::tuple<Tp...>>;
491 
496  {
497  if(m_store() && !bundle_type::m_explicit_push())
498  {
500  std::get<index_of<Tp, data_type>::value>(m_data), m_scope, m_hash));
501  }
502  }
503 
504  // start components
505  auto&& _data = mpl::get_reference_tuple<select_tuple_t>(m_data);
506  invoke::invoke<operation::standard_start, Tag>(_data, std::forward<Args>(args)...);
507  return get_this_type();
508 }
509 
510 //--------------------------------------------------------------------------------------//
511 //
512 template <typename Tag, typename BundleT, typename TupleT>
513 template <typename... Tp, typename... Args>
516 {
517  if(!m_enabled())
518  return get_this_type();
519 
520  using select_tuple_t = mpl::sort<trait::stop_priority, std::tuple<Tp...>>;
521 
522  // stop components
523  auto&& _data = mpl::get_reference_tuple<select_tuple_t>(m_data);
524  invoke::invoke<operation::standard_start, Tag>(_data, std::forward<Args>(args)...);
525 
528  {
529  if(m_store() && !bundle_type::m_explicit_pop())
530  {
533  }
534  }
535  return get_this_type();
536 }
537 
538 //--------------------------------------------------------------------------------------//
539 // start/stop functions
540 //
541 template <typename Tag, typename BundleT, typename TupleT>
542 template <typename... Args>
545 {
546  if(!m_enabled())
547  return get_this_type();
548 
549  // push components into the call-stack
552  {
553  if(m_store() && !bundle_type::m_explicit_push())
554  push();
555  }
556 
557  // start components
558  start(mpl::lightweight{}, std::forward<Args>(args)...);
559  return get_this_type();
560 }
561 
562 //--------------------------------------------------------------------------------------//
563 //
564 template <typename Tag, typename BundleT, typename TupleT>
565 template <typename... Args>
568 {
569  if(!m_enabled())
570  return get_this_type();
571 
572  // stop components
573  stop(mpl::lightweight{}, std::forward<Args>(args)...);
574 
575  // pop components off of the call-stack stack
578  {
579  if(m_store() && !bundle_type::m_explicit_pop())
580  pop();
581  }
582  return get_this_type();
583 }
584 
585 //--------------------------------------------------------------------------------------//
586 // recording
587 //
588 template <typename Tag, typename BundleT, typename TupleT>
589 template <typename... Args>
592 {
593  if(!m_enabled())
594  return get_this_type();
595 
596  ++m_laps;
597  return invoke<operation::record>(std::forward<Args>(args)...);
598 }
599 
600 //--------------------------------------------------------------------------------------//
601 // reset data
602 //
603 template <typename Tag, typename BundleT, typename TupleT>
604 template <typename... Args>
607 {
608  m_laps = 0;
609  return invoke<operation::reset>(std::forward<Args>(args)...);
610 }
611 
612 //--------------------------------------------------------------------------------------//
613 //
614 //
615 template <typename Tag, typename BundleT, typename TupleT>
616 uint64_t
618 {
619  uint64_t _count = 0;
620  invoke::invoke<operation::generic_counter>(m_data, std::ref(_count));
621  return _count;
622 }
623 
624 //--------------------------------------------------------------------------------------//
625 //
626 //
627 template <typename Tag, typename BundleT, typename TupleT>
628 template <typename... Args>
631 {
632  // using construct_t = operation_t<operation::construct>;
633  // apply_v::access<construct_t>(m_data, std::forward<Args>(_args)...);
634  return invoke<operation::construct>(std::forward<Args>(_args)...);
635 }
636 
637 //--------------------------------------------------------------------------------------//
638 //
639 //
640 template <typename Tag, typename BundleT, typename TupleT>
641 template <typename... Args>
644 {
645  return invoke<operation::assemble>(std::forward<Args>(_args)...);
646 }
647 
648 //--------------------------------------------------------------------------------------//
649 //
650 //
651 template <typename Tag, typename BundleT, typename TupleT>
652 template <typename... Args>
655 {
656  return invoke<operation::derive>(std::forward<Args>(_args)...);
657 }
658 
659 //--------------------------------------------------------------------------------------//
660 //
661 //
662 template <typename Tag, typename BundleT, typename TupleT>
663 template <typename... Args>
666 {
667  return invoke<operation::mark>(std::forward<Args>(_args)...);
668 }
669 
670 //--------------------------------------------------------------------------------------//
671 //
672 //
673 template <typename Tag, typename BundleT, typename TupleT>
674 template <typename... Args>
677 {
678  return invoke<operation::mark_begin>(std::forward<Args>(_args)...);
679 }
680 
681 //--------------------------------------------------------------------------------------//
682 //
683 //
684 template <typename Tag, typename BundleT, typename TupleT>
685 template <typename... Args>
688 {
689  return invoke<operation::mark_end>(std::forward<Args>(_args)...);
690 }
691 
692 //--------------------------------------------------------------------------------------//
693 //
694 //
695 template <typename Tag, typename BundleT, typename TupleT>
696 template <typename... Args>
699 {
700  if(!m_enabled())
701  return get_this_type();
702 
703  m_is_active(true);
704  invoke<operation::store>(std::forward<Args>(_args)...);
705  m_is_active(false);
706  return get_this_type();
707 }
708 
709 //--------------------------------------------------------------------------------------//
710 //
711 //
712 template <typename Tag, typename BundleT, typename TupleT>
713 template <typename... Args>
716 {
717  return invoke<operation::audit>(std::forward<Args>(_args)...);
718 }
719 
720 //--------------------------------------------------------------------------------------//
721 //
722 //
723 template <typename Tag, typename BundleT, typename TupleT>
724 template <typename... Args>
727 {
728  return invoke<operation::add_secondary>(std::forward<Args>(_args)...);
729 }
730 
731 //--------------------------------------------------------------------------------------//
732 //
733 //
734 template <typename Tag, typename BundleT, typename TupleT>
735 template <template <typename> class OpT, typename... Args>
738 {
739  if(!m_enabled())
740  return get_this_type();
741 
742  invoke::invoke<OpT, Tag>(m_data, std::forward<Args>(_args)...);
743  return get_this_type();
744 }
745 
746 //--------------------------------------------------------------------------------------//
747 //
748 //
749 template <typename Tag, typename BundleT, typename TupleT>
750 template <template <typename> class OpT, typename... Tp, typename... Args>
753 {
754  if(!m_enabled())
755  return get_this_type();
756 
758  this->get<Tp>(), std::forward<Args>(_args)...));
759  return get_this_type();
760 }
761 
762 //--------------------------------------------------------------------------------------//
763 // get data
764 //
765 template <typename Tag, typename BundleT, typename TupleT>
766 template <typename... Args>
767 auto
769 {
770  return invoke::get<Tag>(m_data, std::forward<Args>(args)...);
771 }
772 
773 //--------------------------------------------------------------------------------------//
774 // get labeled data
775 //
776 template <typename Tag, typename BundleT, typename TupleT>
777 template <typename... Args>
778 auto
780 {
781  return invoke::get_labeled<Tag>(m_data, std::forward<Args>(args)...);
782 }
783 
784 //--------------------------------------------------------------------------------------//
785 //
786 template <typename Tag, typename BundleT, typename TupleT>
789 {
790  return m_data;
791 }
792 
793 //--------------------------------------------------------------------------------------//
794 //
795 template <typename Tag, typename BundleT, typename TupleT>
798 {
799  return m_data;
800 }
801 
802 //--------------------------------------------------------------------------------------//
803 //
804 //
805 template <typename Tag, typename BundleT, typename TupleT>
807 bundle<Tag, BundleT, TupleT>::get(void*& ptr, size_t _hash) const
808 {
809  if(!m_enabled())
810  return get_this_type();
811 
812  tim::variadic::impl::get<Tag>(m_data, ptr, _hash);
813  return get_this_type();
814 }
815 
816 //--------------------------------------------------------------------------------------//
817 //
818 //
819 template <typename Tag, typename BundleT, typename TupleT>
820 template <typename... Tail>
823 {
825  this->get_reference<Tail>() });
826  return get_this_type();
827 }
828 
829 //--------------------------------------------------------------------------------------//
830 //
831 //
832 template <typename Tag, typename BundleT, typename TupleT>
833 template <typename... T, typename... Args>
834 std::array<bool, sizeof...(T)>
836 {
837  if(!m_enabled())
838  return std::array<bool, sizeof...(T)>{};
839 
840  constexpr auto N = sizeof...(T);
841  return TIMEMORY_FOLD_EXPANSION(bool, N, init<T>(std::forward<Args>(args)...));
842 }
843 
844 //--------------------------------------------------------------------------------------//
845 //
846 template <typename Tag, typename BundleT, typename TupleT>
847 template <typename T, typename Func, typename... Args,
850 bundle<Tag, BundleT, TupleT>::type_apply(Func&& _func, Args&&... _args)
851 {
852  if(!m_enabled())
853  return get_this_type();
854 
855  auto* _obj = get<T>();
856  if(_obj)
857  ((*_obj).*(_func))(std::forward<Args>(_args)...);
858  return get_this_type();
859 }
860 
861 //--------------------------------------------------------------------------------------//
862 //
863 template <typename Tag, typename BundleT, typename TupleT>
864 template <typename T, typename Func, typename... Args,
868 {
869  return get_this_type();
870 }
871 
872 //--------------------------------------------------------------------------------------//
873 //
874 template <typename Tag, typename BundleT, typename TupleT>
875 void
877 {
878  if(!m_enabled())
879  return;
880 
881  invoke::set_prefix<Tag>(m_data, m_hash, _key);
882 }
883 
884 //--------------------------------------------------------------------------------------//
885 //
886 template <typename Tag, typename BundleT, typename TupleT>
889 {
890  if(!m_enabled())
891  return get_this_type();
892 
893  auto itr = get_hash_ids()->find(_hash);
894  if(itr != get_hash_ids()->end())
895  invoke::set_prefix<Tag>(m_data, _hash, itr->second);
896  return get_this_type();
897 }
898 
899 //--------------------------------------------------------------------------------------//
900 //
901 template <typename Tag, typename BundleT, typename TupleT>
904 {
905  return set_prefix(_loc.get_hash());
906 }
907 
908 //--------------------------------------------------------------------------------------//
909 //
910 template <typename Tag, typename BundleT, typename TupleT>
913 {
914  if(!m_enabled())
915  return get_this_type();
916 
917  m_scope = val;
918  invoke::set_scope<Tag>(m_data, m_scope);
919  return get_this_type();
920 }
921 
922 //--------------------------------------------------------------------------------------//
923 //
924 template <typename Tag, typename BundleT, typename TupleT>
927 {
928  return scope::transient_destructor{ [&]() { this->stop(); } };
929 }
930 
931 //--------------------------------------------------------------------------------------//
932 //
933 template <typename Tag, typename BundleT, typename TupleT>
937 {
938  return scope::transient_destructor{ [&, _func]() { _func(get_this_type()); } };
939 }
940 
941 //--------------------------------------------------------------------------------------//
942 //
943 template <typename Tag, typename BundleT, typename TupleT>
944 template <typename T>
945 void
946 bundle<Tag, BundleT, TupleT>::set_prefix(T* obj, internal_tag) const
947 {
948  if(!m_enabled())
949  return;
950 
952  auto _key = get_hash_identifier_fast(m_hash);
953  PrefixOpT(obj, m_hash, _key);
954 }
955 
956 //--------------------------------------------------------------------------------------//
957 //
958 template <typename Tag, typename BundleT, typename TupleT>
959 template <typename T>
960 void
961 bundle<Tag, BundleT, TupleT>::set_scope(T* obj, internal_tag) const
962 {
963  if(!m_enabled())
964  return;
965 
967  PrefixOpT(obj, m_scope);
968 }
969 
970 //----------------------------------------------------------------------------------//
971 //
972 template <typename Tag, typename BundleT, typename TupleT>
973 template <bool PrintPrefix, bool PrintLaps>
975 bundle<Tag, BundleT, TupleT>::print(std::ostream& os, bool _endl) const
976 {
977  using printer_t = typename bundle_type::print_type;
978  if(size() == 0 || m_hash == 0)
979  return get_this_type();
980  std::stringstream ss_data;
981  apply_v::access_with_indices<printer_t>(m_data, std::ref(ss_data), false);
982  if(PrintPrefix)
983  {
984  bundle_type::update_width();
985  std::stringstream ss_prefix;
986  std::stringstream ss_id;
987  ss_id << get_prefix() << " " << std::left << key();
988  ss_prefix << std::setw(bundle_type::output_width()) << std::left << ss_id.str()
989  << " : ";
990  os << ss_prefix.str();
991  }
992  os << ss_data.str();
993  if(m_laps > 0 && PrintLaps)
994  os << " [laps: " << m_laps << "]";
995  if(_endl)
996  os << '\n';
997  return get_this_type();
998 }
999 
1000 //----------------------------------------------------------------------------------//
1001 //
1002 template <typename Tag, typename BundleT, typename TupleT>
1003 template <typename Archive>
1004 void
1005 bundle<Tag, BundleT, TupleT>::serialize(Archive& ar, const unsigned int)
1006 {
1007  std::string _key = {};
1008  auto keyitr = get_hash_ids()->find(m_hash);
1009  if(keyitr != get_hash_ids()->end())
1010  _key = keyitr->second;
1011 
1012  ar(cereal::make_nvp("hash", m_hash), cereal::make_nvp("key", _key),
1013  cereal::make_nvp("laps", m_laps));
1014 
1015  if(keyitr == get_hash_ids()->end())
1016  {
1017  auto _hash = add_hash_id(_key);
1018  if(_hash != m_hash)
1019  {
1020  PRINT_HERE("Warning! Hash for '%s' (%llu) != %llu", _key.c_str(),
1021  (unsigned long long) _hash, (unsigned long long) m_hash);
1022  }
1023  }
1024 
1025  ar.setNextName("data");
1026  ar.startNode();
1027  invoke::serialize(ar, m_data);
1028  ar.finishNode();
1029  // ar(cereal::make_nvp("data", m_data));
1030 }
1031 
1032 //--------------------------------------------------------------------------------------//
1033 
1034 } // namespace tim
1035 
1036 #endif
Example: bundle<Tag, component_bundle<Foo>, mixed_wrapper_types<concat<Bar, Baz>>> will use Tag + tra...
Definition: bundle.hpp:113
typename TupleT::template data_type< Tag > data_type
Definition: bundle.hpp:153
typename TupleT::type_list_type type_list_type
Definition: bundle.hpp:154
tim::variadic::impl::quirk_config< T, reference_type, U... > quirk_config
Definition: bundle.hpp:164
typename bundle_type::string_t string_t
Definition: bundle.hpp:145
typename TupleT::template this_type< BundleT > this_type
Definition: bundle.hpp:150
std::function< void(this_type &)> initializer_type
Definition: bundle.hpp:157
#define IF_CONSTEXPR(...)
Definition: language.hpp:72
void serialize(std::string fname, exec_data< Counter > &obj)
Definition: counter.hpp:322
void set_scope(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:792
void assemble(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:850
void mark_begin(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:474
void set_prefix(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:756
void audit(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:921
void store(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:546
auto serialize(ArchiveT &ar, TupleT< Tp... > &obj)
void record(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:616
void derive(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:886
void pop(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:721
void stop(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:368
void measure(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:651
void push(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:686
void mark_end(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:510
void mark(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:439
void reset(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:581
void print(std::ostream &os, Args &&... args)
Definition: functional.cpp:159
void start(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:298
impl::filter_false_after_decay_t< trait::is_available, type_list< Types... > > implemented_t
filter out any types that are not available
Definition: available.hpp:318
convert_t< typename ::tim::mpl::impl::sortT< PrioT, convert_t< Tuple, type_list<> >, convert_t< BegT, type_list<> >, convert_t< EndT, type_list<> >>::type, std::tuple<> > sort
Definition: filters.hpp:454
a generic type for indicating that function call or constructor should be as lightweight as possible.
Definition: types.hpp:328
Ret invoke(string_view_t &&label, Func &&func, Args &&... args)
Definition: invoker.hpp:39
std::array< Tp, N > & operator-=(std::array< Tp, N > &lhs, const std::array< Tp, N > &rhs)
Definition: stl.hpp:176
A light-weight alternative to std::function. Pass any callback - including capturing lambdas - cheapl...
Definition: kokkosp.cpp:38
size_t hash_value_t
Definition: types.hpp:81
typename impl::convert_each< T, U... >::type convert_each_t
Definition: types.hpp:819
add_secondary
Definition: settings.cpp:1371
typename std::remove_pointer< U >::type remove_pointer_t
Definition: types.hpp:530
void consume_parameters(ArgsT &&...) TIMEMORY_HIDDEN
Definition: types.hpp:285
impl::index_of< Tp, Type > index_of
Definition: types.hpp:536
typename std::enable_if< B, T >::type enable_if_t
Alias template for enable_if.
Definition: types.hpp:190
auto get_labeled(const auto_bundle< Tag, Types... > &_obj)
string_view_t get_hash_identifier_fast(hash_value_t _hash)
this does not check other threads or aliases. Only call this function when you know that the hash exi...
Definition: types.hpp:237
void init(Args &&... args)
Definition: types.hpp:111
hash_map_ptr_t & get_hash_ids()
tim::mpl::apply< std::string > string
Definition: macros.hpp:52
hash_value_t add_hash_id(hash_map_ptr_t &_hash_map, const string_view_t &_prefix)
add an string to the given hash-map (if it doesn't already exist) and return the hash
Definition: types.hpp:187
auto get(const auto_bundle< Tag, Types... > &_obj)
typename impl::convert< T, U >::type convert_t
Definition: types.hpp:816
Static polymorphic base class for component bundlers.
Definition: bundle.hpp:51
The declaration for the types for settings without definitions.
This operation class is similar to pointer_operator but can handle non-pointer types.
Definition: generic.hpp:55
a variadic type which holds zero or more quirks that are passed to the constructor of a component bun...
Definition: quirks.hpp:39
this data type encodes the options of storage scope. The default is hierarchical (tree) scope....
Definition: types.hpp:446
const hash_value_t & get_hash() const
trait that designates whether there is a priority when starting the type w.r.t. other types....
trait that designates whether there is a priority when stopping the type w.r.t. other types....
#define PRINT_HERE(...)
Definition: macros.hpp:147
#define TIMEMORY_FOLD_EXPRESSION(...)
Definition: types.hpp:55
#define TIMEMORY_FOLD_EXPANSION(TYPE, SIZE,...)
Definition: types.hpp:63