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.
lightweight_tuple.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
15// all 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
26/** \file timemory/variadic/lightweight_tuple.hpp
27 * This is the C++ class that bundles together components and enables
28 * operation on the components as a single entity
29 *
30 */
31
32#pragma once
33
34#include "timemory/backends/dmp.hpp"
41#include "timemory/tpls/cereal/cereal.hpp"
47
48#include <cstdint>
49#include <cstdio>
50#include <fstream>
51#include <functional>
52#include <iomanip>
53#include <ios>
54#include <iostream>
55#include <string>
56
57namespace tim
58{
59/// \class tim::lightweight_tuple
60/// \tparam Types Specification of the component types to bundle together
61///
62/// \brief This is a variadic component wrapper which provides the least amount of
63/// runtime and compilation overhead.
64///
65///
66template <typename... Types>
68: public stack_bundle<mpl::available_t<type_list<Types...>>>
70{
71protected:
74 using impl_type = typename bundle_type::impl_type;
75
76 template <typename... Tp>
77 friend class impl::base_bundle;
78
79public:
81
82 using this_type = lightweight_tuple<Types...>;
83 using type_list_type = type_list<Types...>;
84
86 using tuple_type = typename bundle_type::tuple_type;
87 using sample_type = typename bundle_type::sample_type;
88 using reference_type = typename bundle_type::reference_type;
89 using user_bundle_types = typename bundle_type::user_bundle_types;
90
91 using size_type = typename bundle_type::size_type;
93
94 template <template <typename> class Op, typename Tuple = impl_type>
95 using operation_t = typename bundle_type::template generic_operation<Op, Tuple>::type;
96
97 template <template <typename> class Op, typename Tuple = impl_type>
99 typename bundle_type::template custom_operation<Op, Tuple>::type;
100
104 using initializer_type = std::function<void(this_type&)>;
106
107 static constexpr bool has_gotcha_v = bundle_type::has_gotcha_v;
108 static constexpr bool has_user_bundle_v = bundle_type::has_user_bundle_v;
109
110public:
112 {
113 static initializer_type _instance = [](this_type&) {};
114 return _instance;
115 }
116
117 template <typename T, typename... U>
118 using quirk_config = tim::variadic::impl::quirk_config<T, type_list<Types...>, U...>;
119
120public:
121 lightweight_tuple() = default;
122
123 template <typename... T>
126
127 template <typename... T>
130
131 template <typename... T>
132 explicit lightweight_tuple(size_t _hash, quirk::config<T...> = {},
134
135 explicit lightweight_tuple(size_t _hash, scope::config _scope,
137
138 explicit lightweight_tuple(const string_t& key, scope::config _scope,
140
141 explicit lightweight_tuple(const captured_location_t& loc, scope::config _scope,
143
145
146 //------------------------------------------------------------------------//
147 // Copy construct and assignment
148 //------------------------------------------------------------------------//
151
154
155 lightweight_tuple clone(bool store, scope::config _scope = scope::get_default());
156
157public:
158 //----------------------------------------------------------------------------------//
159 // public static functions
160 //
161 static constexpr std::size_t size() { return std::tuple_size<tuple_type>::value; }
162
163 /// requests the component initialize their storage
164 static void init_storage();
165
166 //----------------------------------------------------------------------------------//
167 // public member functions
168 //
169 /// generic push into storage
170 this_type& push();
171
172 /// generic pop out of storage
173 this_type& pop();
174
175 /// selective push
176 template <typename... Tp>
178
179 /// selective push
180 template <typename... Tp>
182
183 /// selective pop
184 template <typename... Tp>
186
187 /// selective pop
188 template <typename... Tp>
190
191 /// start all applicable components
192 template <typename... Args>
193 this_type& start(Args&&...);
194
195 /// selective start
196 template <typename... Tp, typename... Args>
198
199 /// selective start
200 template <typename... Tp, typename... Args>
202
203 /// stop all applicable components
204 template <typename... Args>
205 this_type& stop(Args&&...);
206
207 /// selective stop
208 template <typename... Tp, typename... Args>
210
211 /// selection stop
212 template <typename... Tp, typename... Args>
214
215 /// generic
216 template <typename... Args>
217 this_type& measure(Args&&...);
218
219 /// generic
220 template <typename... Args>
221 this_type& sample(Args&&...);
222
223 /// generic
224 template <typename... Args>
225 this_type& record(Args&&...);
226
227 /// generic
228 template <typename... Args>
229 this_type& reset(Args&&...);
230
231 /// generic
232 template <typename... Args>
233 auto get(Args&&...) const;
234
235 /// generic
236 template <typename... Args>
237 auto get_labeled(Args&&...) const;
238
239 /// get tuple
240 data_type& data();
241
242 /// get tuple
243 const data_type& data() const;
244
245 /// set scope configuration
247
248 using bundle_type::get_prefix;
249 using bundle_type::get_scope;
250 using bundle_type::get_store;
251 using bundle_type::hash;
252 using bundle_type::key;
253 using bundle_type::laps;
254 using bundle_type::prefix;
255 using bundle_type::store;
256
257 /// when chaining together operations, this function enables executing a function
258 /// inside the chain
259 template <typename FuncT, typename... Args>
260 decltype(auto) execute(FuncT&& func, Args&&... args)
261 {
262 return mpl::execute(*this,
263 std::forward<FuncT>(func)(std::forward<Args>(args)...));
264 }
265
266 /// construct the objects that have constructors with matching arguments
267 //
268 template <typename... Args>
270 {
271 using construct_t = operation_t<operation::construct>;
272 apply_v::access<construct_t>(m_data, std::forward<Args>(_args)...);
273 return get_this_type();
274 }
275
276 /// provide preliminary info to the objects with matching arguments. This is typically
277 /// used to notify a component that it has been bundled alongside another component
278 /// that it can extract data from.
279 //
281
282 template <typename... Args, size_t N = sizeof...(Args), enable_if_t<N != 0, int> = 0>
284 {
285 invoke::assemble(m_data, std::forward<Args>(_args)...);
286 return get_this_type();
287 }
288
289 /// provide conclusive info to the objects with matching arguments. This is typically
290 /// used by components to extract data from another component it has been bundled
291 /// alongside, e.g. the cpu_util component can extract data from \ref
292 /// tim::component::wall_clock and \ref tim::component::cpu_clock
293 //
295
296 template <typename... Args, size_t N = sizeof...(Args), enable_if_t<N != 0, int> = 0>
298 {
299 invoke::derive(m_data, std::forward<Args>(_args)...);
300 return get_this_type();
301 }
302
303 /// mark a beginning position in the execution (typically used by asynchronous
304 /// structures)
305 //
306 template <typename... Args>
308 {
309 invoke::mark_begin(m_data, std::forward<Args>(_args)...);
310 return get_this_type();
311 }
312
313 /// mark a beginning position in the execution (typically used by asynchronous
314 /// structures)
315 //
316 template <typename... Args>
318 {
319 invoke::mark_end(m_data, std::forward<Args>(_args)...);
320 return get_this_type();
321 }
322
323 /// store a value
324 template <typename... Args>
326 {
327 invoke::store(m_data, std::forward<Args>(_args)...);
328 return get_this_type();
329 }
330
331 /// allow the components to inspect the incoming arguments before start
332 /// or out-going return value before returning (typically using in GOTCHA components)
333 //
334 template <typename... Args>
336 {
337 invoke::audit(m_data, std::forward<Args>(_args)...);
338 return get_this_type();
339 }
340
341 /// perform an add_secondary operation. This operation allows components to add
342 /// additional entries to storage which are their direct descendant
343 template <typename... Args>
345 {
346 return invoke<operation::add_secondary>(std::forward<Args>(_args)...);
347 }
348
349 /// perform an add_secondary operation. This operation allows components to add
350 /// additional entries to storage which are their direct descendant
351 template <typename... Args>
353 {
354 return invoke<operation::add_statistics>(std::forward<Args>(_args)...);
355 }
356
357 /// \tparam OpT Operation struct
358 /// \brief apply a user-defined operation to all the components
359 template <template <typename> class OpT, typename... Args>
361 {
362 invoke::invoke<OpT>(m_data, std::forward<Args>(_args)...);
363 return get_this_type();
364 }
365
366 /// \tparam OpT Operation struct
367 /// \brief generic member function for invoking user-provided operations on a specific
368 /// set of component types
369 template <template <typename> class OpT, typename... Tp, typename... Args>
371 {
372 invoke_piecewise<OpT>(mpl::available_t<type_list<Tp...>>{},
373 std::forward<Args>(_args)...);
374 return get_this_type();
375 }
376
377 /// \tparam OpT Operation struct
378 /// \brief generic member function for invoking user-provided operations on a specific
379 /// set of component types
380 template <template <typename> class OpT, typename... Tp, typename... Args>
382 {
383 invoke_piecewise<OpT>(
385 std::forward<Args>(_args)...);
386 return get_this_type();
387 }
388
389 /// get member functions taking either a type
390 template <typename T, enable_if_t<is_one_of<T, data_type>::value, int> = 0>
391 T* get()
392 {
393 return &(std::get<index_of<T, data_type>::value>(m_data));
394 }
395
396 template <typename T, enable_if_t<is_one_of<T, data_type>::value, int> = 0>
397 const T* get() const
398 {
399 return &(std::get<index_of<T, data_type>::value>(m_data));
400 }
401
402 template <typename T, enable_if_t<!is_one_of<T, data_type>::value, int> = 0>
403 T* get() const
404 {
405 void* ptr = nullptr;
406 get(ptr, typeid_hash<T>());
407 return static_cast<T*>(ptr);
408 }
409
410 this_type& get(void*& ptr, size_t _hash) const
411 {
412 using get_t = operation_t<operation::get>;
413 apply_v::access<get_t>(m_data, ptr, _hash);
414 return get_this_type();
415 }
416
417 /// get member functions finding component and applying lambda
418 template <typename T, typename FuncT>
419 decltype(auto) get(FuncT&& _func);
420
421 template <typename T, typename FuncT>
422 decltype(auto) get(FuncT&& _func) const;
423
424 //----------------------------------------------------------------------------------//
425 /// this is a simple alternative to get<T>() when used from SFINAE in operation
426 /// namespace which has a struct get also templated. Usage there can cause error
427 /// with older compilers
428 template <typename U, typename T = std::remove_pointer_t<decay_t<U>>,
429 enable_if_t<trait::is_available<T>::value && is_one_of<T, data_type>::value,
430 int> = 0>
432 {
433 return get<T>();
434 }
435
436 //----------------------------------------------------------------------------------//
437
438 template <
439 typename T, typename... Args,
441 bool init(Args&&...)
442 {
443 using bundle_t = decltype(std::get<0>(std::declval<user_bundle_types>()));
444 this->init<bundle_t>();
445 this->get<bundle_t>()->insert(component::factory::get_opaque<T>(m_scope),
446 component::factory::get_typeids<T>());
447 return true;
448 }
449
450 //----------------------------------------------------------------------------------//
451
452 template <
453 typename T, typename... Args,
455 bool init(Args&&...)
456 {
458 }
459
460 //----------------------------------------------------------------------------------//
461 /// variadic initialization
462 //
463 template <typename... T, typename... Args>
464 auto initialize(Args&&... args)
465 {
466 constexpr auto N = sizeof...(T);
467 return TIMEMORY_FOLD_EXPANSION(bool, N,
468 this->init<T>(std::forward<Args>(args)...));
469 }
470
471 //----------------------------------------------------------------------------------//
472 /// apply a member function to a type that is in variadic list AND is available
473 ///
474 template <typename T, typename Func, typename... Args,
476 this_type& type_apply(Func&& _func, Args&&... _args)
477 {
478 auto&& _obj = get<T>();
479 ((_obj).*(_func))(std::forward<Args>(_args)...);
480 return get_this_type();
481 }
482
483 template <typename T, typename Func, typename... Args,
485 this_type& type_apply(Func&&, Args&&...)
486 {
487 return get_this_type();
488 }
489
490 //----------------------------------------------------------------------------------//
491 // this_type operators
492 //
493 this_type& operator-=(const this_type& rhs);
495 this_type& operator+=(const this_type& rhs);
497
498 //----------------------------------------------------------------------------------//
499 // generic operators
500 //
501 template <typename Op>
503 {
504 using minus_t = operation_t<operation::minus>;
505 apply_v::access<minus_t>(m_data, std::forward<Op>(rhs));
506 return get_this_type();
507 }
508
509 template <typename Op>
511 {
512 using plus_t = operation_t<operation::plus>;
513 apply_v::access<plus_t>(m_data, std::forward<Op>(rhs));
514 return get_this_type();
515 }
516
517 template <typename Op>
519 {
520 using multiply_t = operation_t<operation::multiply>;
521 apply_v::access<multiply_t>(m_data, std::forward<Op>(rhs));
522 return get_this_type();
523 }
524
525 template <typename Op>
527 {
528 using divide_t = operation_t<operation::divide>;
529 apply_v::access<divide_t>(m_data, std::forward<Op>(rhs));
530 return get_this_type();
531 }
532
533 //----------------------------------------------------------------------------------//
534 // friend operators
535 //
536 friend this_type operator+(const this_type& lhs, const this_type& rhs)
537 {
538 this_type tmp(lhs);
539 return tmp += rhs;
540 }
541
542 friend this_type operator-(const this_type& lhs, const this_type& rhs)
543 {
544 this_type tmp(lhs);
545 return tmp -= rhs;
546 }
547
548 template <typename Op>
549 friend this_type operator*(const this_type& lhs, Op&& rhs)
550 {
551 this_type tmp(lhs);
552 return tmp *= std::forward<Op>(rhs);
553 }
554
555 template <typename Op>
556 friend this_type operator/(const this_type& lhs, Op&& rhs)
557 {
558 this_type tmp(lhs);
559 return tmp /= std::forward<Op>(rhs);
560 }
561
562 //----------------------------------------------------------------------------------//
563 //
564 template <bool PrintPrefix = true, bool PrintLaps = true>
565 this_type& print(std::ostream& os, bool skip_wo_hash = true) const
566 {
567 using printer_t = typename bundle_type::print_type;
568 if(size() == 0)
569 return get_this_type();
570 if(m_hash == 0 && skip_wo_hash)
571 return get_this_type();
572 std::stringstream ss_data;
573 apply_v::access_with_indices<printer_t>(m_data, std::ref(ss_data), false);
574 IF_CONSTEXPR(PrintPrefix)
575 {
576 bundle_type::update_width();
577 auto _key = key();
578 if(_key.length() > 0)
579 {
580 std::stringstream ss_prefix;
581 std::stringstream ss_id;
582 ss_id << get_prefix() << " " << std::left << _key;
583 ss_prefix << std::setw(bundle_type::output_width()) << std::left
584 << ss_id.str() << " : ";
585 os << ss_prefix.str();
586 }
587 }
588 std::string _s = ss_data.str();
589 if(_s.empty())
590 return get_this_type();
591 while(_s.find_last_of(", ") == _s.length() - 1)
592 _s = _s.substr(0, _s.length() - 1);
593 if(_s.empty())
594 return get_this_type();
595 os << _s;
596 if(m_laps > 0 && PrintLaps)
597 os << " [laps: " << m_laps << "]";
598 return get_this_type();
599 }
600
601 //----------------------------------------------------------------------------------//
602 //
603 friend std::ostream& operator<<(std::ostream& os, const this_type& obj)
604 {
605 obj.print<true, true>(os);
606 return os;
607 }
608
609 //----------------------------------------------------------------------------------//
610 //
611 template <typename Archive>
612 void serialize(Archive& ar, const unsigned int)
613 {
614 std::string _key = {};
615 auto keyitr = get_hash_ids()->find(m_hash);
616 if(keyitr != get_hash_ids()->end())
617 _key = keyitr->second;
618
619 ar(cereal::make_nvp("hash", m_hash), cereal::make_nvp("key", _key),
620 cereal::make_nvp("laps", m_laps));
621
622 if(keyitr == get_hash_ids()->end())
623 {
624 auto _hash = add_hash_id(_key);
625 if(_hash != m_hash)
626 {
627 PRINT_HERE("Warning! Hash for '%s' (%llu) != %llu", _key.c_str(),
628 (unsigned long long) _hash, (unsigned long long) m_hash);
629 }
630 }
631
632 ar.setNextName("data");
633 ar.startNode();
635 ar.finishNode();
636 }
637
638public:
639 int64_t laps() const { return bundle_type::laps(); }
640 std::string key() const { return bundle_type::key(); }
641 uint64_t hash() const { return bundle_type::hash(); }
642 bool& store() { return bundle_type::store(); }
643 const bool& store() const { return bundle_type::store(); }
644 auto prefix() const { return bundle_type::prefix(); }
645 auto get_prefix() const { return bundle_type::get_prefix(); }
646
647 TIMEMORY_INLINE void rekey(const string_t& _key);
648 TIMEMORY_INLINE void rekey(const captured_location_t& _loc);
649 TIMEMORY_INLINE void rekey(uint64_t _hash);
650
652 const data_type& get_data() const;
653
654protected:
655 // protected member functions
656 void set_prefix(const string_t&) const;
657 void set_prefix(size_t) const;
658
659protected:
660 // objects
661 using bundle_type::m_config;
662 using bundle_type::m_hash;
663 using bundle_type::m_is_active;
664 using bundle_type::m_is_pushed;
665 using bundle_type::m_laps;
666 using bundle_type::m_scope;
667 using bundle_type::m_store;
669
670private:
671 template <template <typename> class OpT, typename... Tp, typename... Args>
672 void invoke_piecewise(type_list<Tp...>, Args&&... _args)
673 {
675 this->get<Tp>(), std::forward<Args>(_args)...));
676 }
677
678 this_type& get_this_type() { return static_cast<this_type&>(*this); }
679 this_type& get_this_type() const
680 {
681 return const_cast<this_type&>(static_cast<const this_type&>(*this));
682 }
683};
684
685//
686//----------------------------------------------------------------------------------//
687//
688template <typename... Types>
689void
691{
692 m_hash = add_hash_id(_key);
693 set_prefix(_key);
694}
695//
696//----------------------------------------------------------------------------------//
697//
698template <typename... Types>
699void
701{
702 m_hash = _loc.get_hash();
703 set_prefix(_loc.get_hash());
704}
705//
706//----------------------------------------------------------------------------------//
707//
708template <typename... Types>
709void
711{
712 m_hash = _hash;
713 set_prefix(_hash);
714}
715//
716//----------------------------------------------------------------------------------//
717//
718template <typename... Types>
719template <typename T, typename FuncT>
720decltype(auto)
722{
723 auto* _obj = this->get<T>();
724 if(_obj)
725 return std::forward<FuncT>(_func)(_obj);
726 using return_type = decltype(_func(std::declval<decltype(_obj)>()));
727#if defined(CXX17)
728 if constexpr(std::is_void<decay_t<return_type>>::value)
729 return;
730 else if constexpr(std::is_pointer<decay_t<return_type>>::value)
731 return static_cast<decay_t<return_type>>(nullptr);
732 else
733 return decltype(_func(std::declval<decltype(_obj)>())){};
734#else
735 return return_type();
736#endif
737}
738//
739//----------------------------------------------------------------------------------//
740//
741template <typename... Types>
742template <typename T, typename FuncT>
743decltype(auto)
744lightweight_tuple<Types...>::get(FuncT&& _func) const
745{
746 auto* _obj = this->get<T>();
747 if(_obj)
748 return std::forward<FuncT>(_func)(_obj);
749 using return_type = decltype(_func(std::declval<decltype(_obj)>()));
750#if defined(CXX17)
751 if constexpr(std::is_void<decay_t<return_type>>::value)
752 return;
753 else if constexpr(std::is_pointer<decay_t<return_type>>::value)
754 return static_cast<decay_t<return_type>>(nullptr);
755 else
756 return decltype(_func(std::declval<decltype(_obj)>())){};
757#else
758 return return_type();
759#endif
760}
761
762//
763//======================================================================================//
764
765template <typename... Types>
766auto
768 -> decltype(std::declval<lightweight_tuple<Types...>>().get())
769{
770 return _obj.get();
771}
772
773//--------------------------------------------------------------------------------------//
774
775template <typename... Types>
776auto
778 -> decltype(std::declval<lightweight_tuple<Types...>>().get_labeled())
779{
780 return _obj.get_labeled();
781}
782
783//--------------------------------------------------------------------------------------//
784
785} // namespace tim
786
787//======================================================================================//
788//
789// std::get operator
790//
791namespace std
792{
793//--------------------------------------------------------------------------------------//
794
795template <std::size_t N, typename... Types>
796typename std::tuple_element<N, std::tuple<Types...>>::type&
798{
799 return get<N>(obj.data());
800}
801
802//--------------------------------------------------------------------------------------//
803
804template <std::size_t N, typename... Types>
805const typename std::tuple_element<N, std::tuple<Types...>>::type&
806get(const ::tim::lightweight_tuple<Types...>& obj)
807{
808 return get<N>(obj.data());
809}
810
811//--------------------------------------------------------------------------------------//
812
813template <std::size_t N, typename... Types>
814auto
816 -> decltype(get<N>(std::forward<::tim::lightweight_tuple<Types...>>(obj).data()))
817{
818 using obj_type = ::tim::lightweight_tuple<Types...>;
819 return get<N>(std::forward<obj_type>(obj).data());
820}
821
822//======================================================================================//
823} // namespace std
824
825//--------------------------------------------------------------------------------------//
This is a variadic component wrapper which provides the least amount of runtime and compilation overh...
static initializer_type & get_initializer()
lightweight_tuple clone(bool store, scope::config _scope=scope::get_default())
static constexpr std::size_t size()
mpl::append_type_t< quirk::auto_start, this_type > auto_type
this_type & operator-=(Op &&rhs)
this_type & measure(Args &&...)
generic
void set_prefix(const string_t &) const
this_type & invoke(Args &&... _args)
apply a user-defined operation to all the components
decltype(auto) get(FuncT &&_func) const
this_type & pop(mpl::piecewise_select< Tp... >)
selective pop
this_type & reset(Args &&...)
generic
this_type & operator-=(const this_type &rhs)
decltype(auto) get(FuncT &&_func)
get member functions finding component and applying lambda
void serialize(Archive &ar, const unsigned int)
static constexpr bool has_gotcha_v
friend std::ostream & operator<<(std::ostream &os, const this_type &obj)
this_type & type_apply(Func &&_func, Args &&... _args)
apply a member function to a type that is in variadic list AND is available
this_type & get(void *&ptr, size_t _hash) const
convert_t< tuple_type, lightweight_tuple<> > type
this_type & pop()
generic pop out of storage
this_type & store(Args &&... _args)
store a value
typename bundle_type::tuple_type tuple_type
typename bundle_type::reference_type reference_type
this_type & add_secondary(Args &&... _args)
perform an add_secondary operation. This operation allows components to add additional entries to sto...
typename bundle_type::data_type data_type
this_type & start(mpl::piecewise_select< Tp... >, Args &&...)
selective start
this_type & audit(Args &&... _args)
allow the components to inspect the incoming arguments before start or out-going return value before ...
this_type & stop(mpl::piecewise_select< Tp... >, Args &&...)
selective stop
this_type & assemble()
provide preliminary info to the objects with matching arguments. This is typically used to notify a c...
this_type & type_apply(Func &&, Args &&...)
auto get(Args &&...) const
generic
mpl::remove_type_t< quirk::auto_start, this_type > component_type
tim::variadic::impl::quirk_config< T, type_list< Types... >, U... > quirk_config
this_type & operator+=(const this_type &rhs)
this_type & print(std::ostream &os, bool skip_wo_hash=true) const
this_type & start(mpl::piecewise_ignore< Tp... >, Args &&...)
selective start
decltype(auto) execute(FuncT &&func, Args &&... args)
when chaining together operations, this function enables executing a function inside the chain
const bool & store() const
friend this_type operator/(const this_type &lhs, Op &&rhs)
auto get_component()
this is a simple alternative to get<T>() when used from SFINAE in operation namespace which has a str...
std::function< void(this_type &)> initializer_type
this_type & assemble(Args &&... _args)
this_type & push(mpl::piecewise_select< Tp... >)
selective push
lightweight_tuple< Types... > this_type
typename bundle_type::size_type size_type
this_type & push()
generic push into storage
this_type & stop(mpl::piecewise_ignore< Tp... >, Args &&...)
selection stop
source_location::captured captured_location_t
std::string key() const
data_type & get_data()
utility::transient_function< void(this_type &)> transient_func_t
lightweight_tuple & operator=(lightweight_tuple &&)=default
this_type & mark_end(Args &&... _args)
mark a beginning position in the execution (typically used by asynchronous structures)
static constexpr bool has_user_bundle_v
static void init_storage()
requests the component initialize their storage
typename bundle_type::template custom_operation< Op, Tuple >::type custom_operation_t
auto get_labeled(Args &&...) const
generic
this_type & update_statistics(Args &&... _args)
perform an add_secondary operation. This operation allows components to add additional entries to sto...
friend this_type operator*(const this_type &lhs, Op &&rhs)
this_type & operator+=(Op &&rhs)
this_type & invoke(mpl::piecewise_select< Tp... >, Args &&... _args)
generic member function for invoking user-provided operations on a specific set of component types
this_type & stop(Args &&...)
stop all applicable components
typename bundle_type::user_bundle_types user_bundle_types
typename bundle_type::template generic_operation< Op, Tuple >::type operation_t
typename bundle_type::sample_type sample_type
this_type & construct(Args &&... _args)
construct the objects that have constructors with matching arguments
this_type & operator*=(Op &&rhs)
this_type & derive(Args &&... _args)
friend this_type operator-(const this_type &lhs, const this_type &rhs)
friend this_type operator+(const this_type &lhs, const this_type &rhs)
this_type & invoke(mpl::piecewise_ignore< Tp... >, Args &&... _args)
generic member function for invoking user-provided operations on a specific set of component types
this_type & pop(mpl::piecewise_ignore< Tp... >)
selective pop
lightweight_tuple(const lightweight_tuple &)=default
typename bundle_type::string_t string_t
this_type & mark_begin(Args &&... _args)
mark a beginning position in the execution (typically used by asynchronous structures)
lightweight_tuple & operator=(const lightweight_tuple &rhs)=default
this_type & operator/=(Op &&rhs)
this_type & set_scope(scope::config)
set scope configuration
typename bundle_type::impl_type impl_type
this_type & push(mpl::piecewise_ignore< Tp... >)
selective push
T * get()
get member functions taking either a type
data_type & data()
get tuple
auto initialize(Args &&... args)
variadic initialization
this_type & derive()
provide conclusive info to the objects with matching arguments. This is typically used by components ...
this_type & record(Args &&...)
generic
this_type & sample(Args &&...)
generic
lightweight_tuple(lightweight_tuple &&)=default
void rekey(const string_t &_key)
const data_type & get_data() const
this_type & start(Args &&...)
start all applicable components
friend class impl::base_bundle
#define IF_CONSTEXPR(...)
Definition: language.hpp:72
std::string string_t
Definition: library.cpp:57
STL namespace.
std::tuple_element< N, std::tuple< Types... > >::type & get(tim::auto_bundle< Tag, Types... > &obj)
return _hash_map end()
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
hash_map_ptr_t & get_hash_ids()
void assemble(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:868
void mark_begin(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:492
void set_prefix(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:774
void audit(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:939
void store(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:564
auto serialize(ArchiveT &ar, TupleT< Tp... > &obj)
void derive(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:904
void mark_end(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:528
typename impl::remove_type< Tp, Types >::type remove_type_t
remove any instances of a type from a tuple/bundler
Definition: filters.hpp:413
typename impl::append_type< Tp, Types >::type append_type_t
append type to a tuple/bundler
Definition: filters.hpp:409
impl::filter_false< trait::is_available, T > available_t
Definition: available.hpp:324
typename impl::subtract< LhsT, RhsT >::type subtract_t
Definition: filters.hpp:426
auto execute(BundleT &&_bundle, FuncT &&_func, Args &&... _args, enable_if_t< is_invocable< FuncT, Args... >::value &&!std::is_void< std::result_of_t< FuncT(Args...)> >::value, int >)
A light-weight alternative to std::function. Pass any callback - including capturing lambdas - cheapl...
Definition: kokkosp.cpp:39
std::array< char *, 4 > _args
std::string string_t
Definition: utility.hpp:98
typename std::decay< T >::type decay_t
Alias template for decay.
Definition: types.hpp:194
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)
tim::mpl::apply< std::string > string
Definition: macros.hpp:53
const std::string std::ostream * os
typename impl::is_one_of< Tp, Types > is_one_of
check if type is in expansion
Definition: types.hpp:777
auto get(const auto_bundle< Tag, Types... > &_obj)
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.
Declare the storage types.
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:453
const hash_value_t & get_hash() const
convert_t< mpl::non_placeholder_t< mpl::non_quirk_t< type_list< Types... > > >, std::tuple<> > data_type
#define PRINT_HERE(...)
Definition: macros.hpp:152
#define TIMEMORY_FOLD_EXPRESSION(...)
Definition: types.hpp:56
#define TIMEMORY_FOLD_EXPANSION(TYPE, SIZE,...)
Definition: types.hpp:64