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.
auto_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 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
26#pragma once
27
30
31#include <cstddef>
32#include <tuple>
33#include <type_traits>
34#include <utility>
35
36namespace tim
37{
38//--------------------------------------------------------------------------------------//
39/// \class tim::auto_tuple
40/// \tparam Types Specification of the component types to bundle together
41///
42/// \brief This is a variadic component wrapper where all components are allocated
43/// on the stack and cannot be disabled at runtime. This bundler has the lowest
44/// overhead. Accepts unlimited number of template parameters. The constructor starts the
45/// components, the destructor stops the components.
46///
47/// \code{.cpp}
48/// using bundle_t = tim::auto_tuple<wall_clock, cpu_clock, peak_rss>;
49///
50/// void foo()
51/// {
52/// auto bar = bundle_t("foo");
53/// // ...
54/// }
55/// \endcode
56///
57/// The above code will record wall-clock, cpu-clock, and peak-rss. The intermediate
58/// storage will happen on the stack and when the destructor is called, it will add itself
59/// to the call-graph
60///
61template <typename... Types>
63: public auto_base_bundle<TIMEMORY_API, component_tuple<>, auto_tuple<Types...>>
65{
66 using poly_base =
68
69public:
70 using this_type = auto_tuple<Types...>;
71 using base_type = component_tuple<Types...>;
75
76 template <typename... Args>
77 explicit auto_tuple(Args&&... args);
78
79 // copy and move
80 ~auto_tuple() = default;
81 auto_tuple(const auto_tuple&) = default;
82 auto_tuple(auto_tuple&&) = default;
83 auto_tuple& operator=(const auto_tuple&) = default;
85
86 static constexpr std::size_t size() { return poly_base::size(); }
87
88public:
89 this_type& print(std::ostream& os, bool _endl = false) const;
90 friend std::ostream& operator<<(std::ostream& os, const this_type& obj)
91 {
92 obj.print(os, false);
93 return os;
94 }
95};
96//
97template <typename... Types>
98template <typename... Args>
100: poly_base{ std::forward<Args>(args)... }
101{}
102//
103template <typename... Types>
104auto_tuple<Types...>&
105auto_tuple<Types...>::print(std::ostream& os, bool _endl) const
106{
107 os << poly_base::m_temporary;
108 if(_endl)
109 os << '\n';
110 return const_cast<this_type&>(*this);
111}
112//
113//======================================================================================//
114//
115template <typename... Types>
116auto
118{
119 return get(_obj.get_component());
120}
121//
122template <typename... Types>
123auto
125{
126 return get_labeled(_obj.get_component());
127}
128//
129} // namespace tim
130
131//======================================================================================//
132//
133// variadic versions
134//
135#if !defined(TIMEMORY_VARIADIC_BLANK_AUTO_TUPLE)
136# define TIMEMORY_VARIADIC_BLANK_AUTO_TUPLE(tag, ...) \
137 using _TIM_TYPEDEF(__LINE__) = ::tim::auto_tuple<__VA_ARGS__>; \
138 TIMEMORY_BLANK_MARKER(_TIM_TYPEDEF(__LINE__), tag);
139#endif
140
141#if !defined(TIMEMORY_VARIADIC_BASIC_AUTO_TUPLE)
142# define TIMEMORY_VARIADIC_BASIC_AUTO_TUPLE(tag, ...) \
143 using _TIM_TYPEDEF(__LINE__) = ::tim::auto_tuple<__VA_ARGS__>; \
144 TIMEMORY_BASIC_MARKER(_TIM_TYPEDEF(__LINE__), tag);
145#endif
146
147#if !defined(TIMEMORY_VARIADIC_AUTO_TUPLE)
148# define TIMEMORY_VARIADIC_AUTO_TUPLE(tag, ...) \
149 using _TIM_TYPEDEF(__LINE__) = ::tim::auto_tuple<__VA_ARGS__>; \
150 TIMEMORY_MARKER(_TIM_TYPEDEF(__LINE__), tag);
151#endif
152
153//======================================================================================//
154//
155// std::get operator
156//
157//======================================================================================//
158//
159namespace std
160{
161//
162//--------------------------------------------------------------------------------------//
163//
164template <std::size_t N, typename... Types>
165typename std::tuple_element<N, std::tuple<Types...>>::type&
167{
168 return get<N>(obj.data());
169}
170//
171//--------------------------------------------------------------------------------------//
172//
173template <std::size_t N, typename... Types>
174const typename std::tuple_element<N, std::tuple<Types...>>::type&
176{
177 return get<N>(obj.data());
178}
179//
180//--------------------------------------------------------------------------------------//
181//
182template <std::size_t N, typename... Types>
183auto
185 -> decltype(get<N>(std::forward<tim::auto_tuple<Types...>>(obj).data()))
186{
187 using obj_type = tim::auto_tuple<Types...>;
188 return get<N>(std::forward<obj_type>(obj).data());
189}
190//
191//--------------------------------------------------------------------------------------//
192//
193} // namespace std
This is a variadic component wrapper where all components are allocated on the stack and cannot be di...
Definition: auto_tuple.hpp:65
convert_t< mpl::available_t< concat< Types... > >, auto_tuple<> > type
Definition: auto_tuple.hpp:74
auto_tuple(Args &&... args)
Definition: auto_tuple.hpp:99
friend std::ostream & operator<<(std::ostream &os, const this_type &obj)
Definition: auto_tuple.hpp:90
auto_tuple & operator=(const auto_tuple &)=default
auto_tuple< Types... > this_type
Definition: auto_tuple.hpp:70
auto_tuple & operator=(auto_tuple &&)=default
auto_tuple(auto_tuple &&)=default
auto_tuple(const auto_tuple &)=default
this_type & print(std::ostream &os, bool _endl=false) const
Definition: auto_tuple.hpp:105
static constexpr std::size_t size()
Definition: auto_tuple.hpp:86
typename base_type::component_type component_type
Definition: auto_tuple.hpp:73
~auto_tuple()=default
This is a variadic component wrapper where all components are allocated on the stack and cannot be di...
component_tuple< Types... > component_type
STL namespace.
std::tuple_element< N, std::tuple< Types... > >::type & get(tim::auto_bundle< Tag, Types... > &obj)
impl::filter_false< trait::is_available, T > available_t
Definition: available.hpp:324
Definition: kokkosp.cpp:39
typename impl::concat< Types... >::type concat
Definition: types.hpp:707
auto get_labeled(const auto_bundle< Tag, Types... > &_obj)
const std::string std::ostream * os
auto get(const auto_bundle< Tag, Types... > &_obj)
typename impl::convert< T, U >::type convert_t
Definition: types.hpp:855
Static polymorphic base class for automatic start/stop bundlers.
Definition: types.hpp:72