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.
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 
36 namespace 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 ///
61 template <typename... Types>
63 : public auto_base_bundle<TIMEMORY_API, component_tuple<>, auto_tuple<Types...>>
65 {
66  using poly_base =
68 
69 public:
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&&) noexcept = default;
83  auto_tuple& operator=(const auto_tuple&) = default;
84  auto_tuple& operator=(auto_tuple&&) noexcept = default;
85 
86  static constexpr std::size_t size() { return poly_base::size(); }
87 
88 public:
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 //
97 template <typename... Types>
98 template <typename... Args>
100 : poly_base{ std::forward<Args>(args)... }
101 {}
102 //
103 template <typename... Types>
104 auto_tuple<Types...>&
105 auto_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 //
115 template <typename... Types>
116 auto
118 {
119  return get(_obj.get_component());
120 }
121 //
122 template <typename... Types>
123 auto
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 //
159 namespace std
160 {
161 //
162 //--------------------------------------------------------------------------------------//
163 //
164 template <std::size_t N, typename... Types>
165 typename std::tuple_element<N, std::tuple<Types...>>::type&
167 {
168  return get<N>(obj.data());
169 }
170 //
171 //--------------------------------------------------------------------------------------//
172 //
173 template <std::size_t N, typename... Types>
174 const typename std::tuple_element<N, std::tuple<Types...>>::type&
176 {
177  return get<N>(obj.data());
178 }
179 //
180 //--------------------------------------------------------------------------------------//
181 //
182 template <std::size_t N, typename... Types>
183 auto
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
auto_tuple< Types... > this_type
Definition: auto_tuple.hpp:70
auto_tuple(const auto_tuple &)=default
auto_tuple(auto_tuple &&) noexcept=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
friend std::ostream & operator<<(std::ostream &os, const this_type &obj)
Definition: auto_tuple.hpp:90
This is a variadic component wrapper where all components are allocated on the stack and cannot be di...
component_tuple< Types... > component_type
impl::filter_false< trait::is_available, T > available_t
Definition: available.hpp:324
Definition: kokkosp.cpp:38
typename impl::concat< Types... >::type concat
Definition: types.hpp:707
auto get_labeled(const auto_bundle< Tag, Types... > &_obj)
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 automatic start/stop bundlers.
Definition: types.hpp:72