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.
stl.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/** \file timemory/math/stl.hpp
26 * \headerfile timemory/math/stl.hpp "timemory/math/stl.hpp"
27 * Provides operators on common STL structures such as <<, +=, -=, *=, /=, +, -, *, /
28 *
29 */
30
31#pragma once
32
33#include "timemory/math/fwd.hpp"
35
36#include <array>
37#include <chrono>
38#include <ostream>
39#include <tuple>
40#include <utility>
41#include <vector>
42
43namespace tim
44{
45/// \namespace tim::stl
46/// \brief the namespace is provided to hide stl overload from global namespace but
47/// provide a method of using the namespace without a "using namespace tim;"
48inline namespace stl
49{
50//--------------------------------------------------------------------------------------//
51//
52// operator += (same type)
53//
54//--------------------------------------------------------------------------------------//
55
56template <typename Tp, size_t N, typename OtherT>
57std::array<Tp, N>&
58operator+=(std::array<Tp, N>& lhs, OtherT&& rhs)
59{
60 math::plus(lhs, std::forward<OtherT>(rhs));
61 return lhs;
62}
63
64template <typename Lhs, typename Rhs, typename OtherT>
65std::pair<Lhs, Rhs>&
66operator+=(std::pair<Lhs, Rhs>& lhs, OtherT&& rhs)
67{
68 math::plus(lhs, std::forward<OtherT>(rhs));
69 return lhs;
70}
71
72template <typename Tp, typename... ExtraT, typename OtherT>
73std::vector<Tp, ExtraT...>&
74operator+=(std::vector<Tp, ExtraT...>& lhs, OtherT&& rhs)
75{
76 math::plus(lhs, std::forward<OtherT>(rhs));
77 return lhs;
78}
79
80template <typename... Types, typename OtherT>
81std::tuple<Types...>&
82operator+=(std::tuple<Types...>& lhs, OtherT&& rhs)
83{
84 math::plus(lhs, rhs);
85 return lhs;
86}
87
88//--------------------------------------------------------------------------------------//
89//
90// operator -= (same type)
91//
92//--------------------------------------------------------------------------------------//
93
94template <typename Tp, size_t N>
95std::array<Tp, N>&
96operator-=(std::array<Tp, N>& lhs, const std::array<Tp, N>& rhs)
97{
98 math::minus(lhs, rhs);
99 return lhs;
100}
101
102template <typename Lhs, typename Rhs>
103std::pair<Lhs, Rhs>&
104operator-=(std::pair<Lhs, Rhs>& lhs, const std::pair<Lhs, Rhs>& rhs)
105{
106 math::minus(lhs, rhs);
107 return lhs;
108}
109
110template <typename Tp, typename... ExtraT>
111std::vector<Tp, ExtraT...>&
112operator-=(std::vector<Tp, ExtraT...>& lhs, const std::vector<Tp, ExtraT...>& rhs)
113{
114 math::minus(lhs, rhs);
115 return lhs;
116}
117
118template <typename... Types>
119std::tuple<Types...>&
120operator-=(std::tuple<Types...>& lhs, const std::tuple<Types...>& rhs)
121{
122 math::minus(lhs, rhs);
123 return lhs;
124}
125
126//--------------------------------------------------------------------------------------//
127//
128// operator *= (same type)
129//
130//--------------------------------------------------------------------------------------//
131
132template <typename Tp, size_t N>
133std::array<Tp, N>&
134operator*=(std::array<Tp, N>& lhs, const std::array<Tp, N>& rhs)
135{
136 math::multiply(lhs, rhs);
137 return lhs;
138}
139
140template <typename Lhs, typename Rhs>
141std::pair<Lhs, Rhs>&
142operator*=(std::pair<Lhs, Rhs>& lhs, const std::pair<Lhs, Rhs>& rhs)
143{
144 math::multiply(lhs, rhs);
145 return lhs;
146}
147
148template <typename Tp, typename... ExtraT>
149std::vector<Tp, ExtraT...>&
150operator*=(std::vector<Tp, ExtraT...>& lhs, const std::vector<Tp, ExtraT...>& rhs)
151{
152 math::multiply(lhs, rhs);
153 return lhs;
154}
155
156template <typename... Types>
157std::tuple<Types...>&
158operator*=(std::tuple<Types...>& lhs, const std::tuple<Types...>& rhs)
159{
160 math::multiply(lhs, rhs);
161 return lhs;
162}
163
164//--------------------------------------------------------------------------------------//
165//
166// operator /= (same type)
167//
168//--------------------------------------------------------------------------------------//
169
170template <typename Tp, size_t N>
171std::array<Tp, N>&
172operator/=(std::array<Tp, N>& lhs, const std::array<Tp, N>& rhs)
173{
174 math::divide(lhs, rhs);
175 return lhs;
176}
177
178template <typename Lhs, typename Rhs>
179std::pair<Lhs, Rhs>&
180operator/=(std::pair<Lhs, Rhs>& lhs, const std::pair<Lhs, Rhs>& rhs)
181{
182 math::divide(lhs, rhs);
183 return lhs;
184}
185
186template <typename Tp, typename... ExtraT>
187std::vector<Tp, ExtraT...>&
188operator/=(std::vector<Tp, ExtraT...>& lhs, const std::vector<Tp, ExtraT...>& rhs)
189{
190 math::divide(lhs, rhs);
191 return lhs;
192}
193
194template <typename... Types>
195std::tuple<Types...>&
196operator/=(std::tuple<Types...>& lhs, const std::tuple<Types...>& rhs)
197{
198 math::divide(lhs, rhs);
199 return lhs;
200}
201
202//--------------------------------------------------------------------------------------//
203//
204// operator *= (fundamental)
205//
206//--------------------------------------------------------------------------------------//
207
208template <typename Lhs, size_t N, typename Rhs,
209 enable_if_t<std::is_arithmetic<decay_t<Rhs>>::value, int>>
210std::array<Lhs, N>&
211operator*=(std::array<Lhs, N>& lhs, const Rhs& rhs)
212{
213 math::multiply(lhs, rhs);
214 return lhs;
215}
216
217template <typename Lhs, typename Rhs, typename ArithT,
218 enable_if_t<std::is_arithmetic<decay_t<ArithT>>::value, int>>
219std::pair<Lhs, Rhs>&
220operator*=(std::pair<Lhs, Rhs>& lhs, const ArithT& rhs)
221{
222 math::multiply(lhs, rhs);
223 return lhs;
224}
225
226template <typename Lhs, typename Rhs, typename... ExtraT,
227 enable_if_t<std::is_arithmetic<decay_t<Rhs>>::value, int>>
228std::vector<Lhs, ExtraT...>&
229operator*=(std::vector<Lhs, ExtraT...>& lhs, const Rhs& rhs)
230{
231 math::multiply(lhs, rhs);
232 return lhs;
233}
234
235template <typename... Lhs, typename Rhs,
236 enable_if_t<std::is_arithmetic<decay_t<Rhs>>::value, int>>
237std::tuple<Lhs...>&
238operator*=(std::tuple<Lhs...>& lhs, const Rhs& rhs)
239{
240 math::multiply(lhs, rhs);
241 return lhs;
242}
243
244//--------------------------------------------------------------------------------------//
245//
246// operator /= (fundamental)
247//
248//--------------------------------------------------------------------------------------//
249
250template <typename Lhs, size_t N, typename Rhs,
251 enable_if_t<std::is_arithmetic<decay_t<Rhs>>::value, int>>
252std::array<Lhs, N>&
253operator/=(std::array<Lhs, N>& lhs, const Rhs& rhs)
254{
255 math::divide(lhs, rhs);
256 return lhs;
257}
258
259template <typename Lhs, typename Rhs, typename ArithT,
260 enable_if_t<std::is_arithmetic<decay_t<ArithT>>::value, int>>
261std::pair<Lhs, Rhs>&
262operator/=(std::pair<Lhs, Rhs>& lhs, const ArithT& rhs)
263{
264 math::divide(lhs, rhs);
265 return lhs;
266}
267
268template <typename Lhs, typename Rhs, typename... ExtraT,
269 enable_if_t<std::is_arithmetic<decay_t<Rhs>>::value, int>>
270std::vector<Lhs, ExtraT...>&
271operator/=(std::vector<Lhs, ExtraT...>& lhs, const Rhs& rhs)
272{
273 math::divide(lhs, rhs);
274 return lhs;
275}
276
277template <typename... Lhs, typename Rhs,
278 enable_if_t<std::is_arithmetic<decay_t<Rhs>>::value, int>>
279std::tuple<Lhs...>&
280operator/=(std::tuple<Lhs...>& lhs, const Rhs& rhs)
281{
282 math::divide(lhs, rhs);
283 return lhs;
284}
285
286//--------------------------------------------------------------------------------------//
287//
288// operator * (fundamental)
289// operator / (fundamental)
290//
291//--------------------------------------------------------------------------------------//
292
293template <typename Lhs, typename Rhs,
294 enable_if_t<std::is_arithmetic<decay_t<Rhs>>::value, int>>
295Lhs operator*(Lhs lhs, const Rhs& rhs)
296{
297 return (lhs *= rhs);
298}
299
300template <typename Rhs, enable_if_t<std::is_arithmetic<decay_t<Rhs>>::value, int> = 0>
301inline std::chrono::system_clock::time_point&
302operator/=(std::chrono::system_clock::time_point& lhs, Rhs)
303{
304 return lhs;
305}
306
307template <typename Lhs, typename Rhs,
308 enable_if_t<std::is_arithmetic<decay_t<Rhs>>::value, int>>
309Lhs
310operator/(Lhs lhs, const Rhs& rhs)
311{
312 return (lhs /= rhs);
313}
314
315//--------------------------------------------------------------------------------------//
316//
317// operator +
318//
319//--------------------------------------------------------------------------------------//
320
321template <typename Tp, size_t N>
322std::array<Tp, N>
323operator+(std::array<Tp, N> lhs, const std::array<Tp, N>& rhs)
324{
325 math::plus(lhs, rhs);
326 return lhs;
327}
328
329//--------------------------------------------------------------------------------------//
330
331template <typename... Types>
332std::tuple<Types...>
333operator+(std::tuple<Types...> lhs, const std::tuple<Types...>& rhs)
334{
335 math::plus(lhs, rhs);
336 return lhs;
337}
338
339//--------------------------------------------------------------------------------------//
340
341template <typename Lhs, typename Rhs>
342std::pair<Lhs, Rhs>
343operator+(std::pair<Lhs, Rhs> lhs, const std::pair<Lhs, Rhs>& rhs)
344{
345 math::plus(lhs, rhs);
346 return lhs;
347}
348
349//--------------------------------------------------------------------------------------//
350
351template <typename Tp, typename... Extra>
352std::vector<Tp, Extra...>
353operator+(std::vector<Tp, Extra...> lhs, const std::vector<Tp, Extra...>& rhs)
354{
355 math::plus(lhs, rhs);
356 return lhs;
357}
358
359//--------------------------------------------------------------------------------------//
360//
361// operator -
362//
363//--------------------------------------------------------------------------------------//
364
365template <typename Tp, size_t N>
366std::array<Tp, N>
367operator-(std::array<Tp, N> lhs, const std::array<Tp, N>& rhs)
368{
369 math::minus(lhs, rhs);
370 return lhs;
371}
372
373//--------------------------------------------------------------------------------------//
374
375template <typename... Types>
376std::tuple<Types...>
377operator-(std::tuple<Types...> lhs, const std::tuple<Types...>& rhs)
378{
379 math::minus(lhs, rhs);
380 return lhs;
381}
382
383//--------------------------------------------------------------------------------------//
384
385template <typename Lhs, typename Rhs>
386std::pair<Lhs, Rhs>
387operator-(std::pair<Lhs, Rhs> lhs, const std::pair<Lhs, Rhs>& rhs)
388{
389 math::minus(lhs, rhs);
390 return lhs;
391}
392
393//--------------------------------------------------------------------------------------//
394
395template <typename Tp, typename... Extra>
396std::vector<Tp, Extra...>
397operator-(std::vector<Tp, Extra...> lhs, const std::vector<Tp, Extra...>& rhs)
398{
399 math::minus(lhs, rhs);
400 return lhs;
401}
402
403//--------------------------------------------------------------------------------------//
404//
405// operator *
406//
407//--------------------------------------------------------------------------------------//
408
409template <typename Tp, size_t N>
410std::array<Tp, N> operator*(std::array<Tp, N> lhs, const std::array<Tp, N>& rhs)
411{
412 math::multiply(lhs, rhs);
413 return lhs;
414}
415
416//--------------------------------------------------------------------------------------//
417
418template <typename... Types>
419std::tuple<Types...> operator*(std::tuple<Types...> lhs, const std::tuple<Types...>& rhs)
420{
421 math::multiply(lhs, rhs);
422 return lhs;
423}
424
425//--------------------------------------------------------------------------------------//
426
427template <typename Lhs, typename Rhs>
428std::pair<Lhs, Rhs> operator*(std::pair<Lhs, Rhs> lhs, const std::pair<Lhs, Rhs>& rhs)
429{
430 math::multiply(lhs, rhs);
431 return lhs;
432}
433
434//--------------------------------------------------------------------------------------//
435
436template <typename Tp, typename... Extra>
437std::vector<Tp, Extra...> operator*(std::vector<Tp, Extra...> lhs,
438 const std::vector<Tp, Extra...>& rhs)
439{
440 math::multiply(lhs, rhs);
441 return lhs;
442}
443
444//--------------------------------------------------------------------------------------//
445//
446// operator /
447//
448//--------------------------------------------------------------------------------------//
449
450template <typename Tp, size_t N>
451std::array<Tp, N>
452operator/(std::array<Tp, N> lhs, const std::array<Tp, N>& rhs)
453{
454 math::divide(lhs, rhs);
455 return lhs;
456}
457
458//--------------------------------------------------------------------------------------//
459
460template <typename... Types>
461std::tuple<Types...>
462operator/(std::tuple<Types...> lhs, const std::tuple<Types...>& rhs)
463{
464 math::divide(lhs, rhs);
465 return lhs;
466}
467
468//--------------------------------------------------------------------------------------//
469
470template <typename Lhs, typename Rhs>
471std::pair<Lhs, Rhs>
472operator/(std::pair<Lhs, Rhs> lhs, const std::pair<Lhs, Rhs>& rhs)
473{
474 math::divide(lhs, rhs);
475 return lhs;
476}
477
478//--------------------------------------------------------------------------------------//
479
480template <typename Tp, typename... Extra>
481std::vector<Tp, Extra...>
482operator/(std::vector<Tp, Extra...> lhs, const std::vector<Tp, Extra...>& rhs)
483{
484 math::divide(lhs, rhs);
485 return lhs;
486}
487
488} // namespace stl
489
490} // namespace tim
491
492namespace std
493{
494#if defined(TIMEMORY_WINDOWS)
495
496template <typename Lhs, typename Rhs>
497const pair<Lhs, Rhs>
498operator-(pair<Lhs, Rhs> lhs, const pair<Lhs, Rhs>& rhs)
499{
500 ::tim::math::minus(lhs, rhs);
501 return lhs;
502}
503
504template <typename... Types>
505const tuple<Types...>
506operator-(tuple<Types...> lhs, const tuple<Types...>& rhs)
507{
508 ::tim::math::minus(lhs, rhs);
509 return lhs;
510}
511
512#endif
513
514template <typename Tp>
515tuple<>&
516operator+=(tuple<>& _lhs, const Tp&)
517{
518 return _lhs;
519}
520
521} // namespace std
STL namespace.
::tim::statistics< tuple<> > & operator+=(::tim::statistics< tuple<> > &_lhs, const Tp &)
Definition: statistics.hpp:338
Tp operator-(const base< Tp, Value > &lhs, const base< Tp, Value > &rhs)
Definition: definition.hpp:306
Tp & plus(Tp &, const Up &)
Definition: plus.hpp:106
auto divide(Tp &_lhs, Up _rhs, type_list<>,...) -> decltype(_lhs/=_rhs, void())
Definition: divide.hpp:43
Tp & minus(Tp &, const Up &)
Definition: minus.hpp:98
Tp & multiply(Tp &, const Up &)
Definition: multiply.hpp:140
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:172
std::array< Tp, N > operator-(std::array< Tp, N > lhs, const std::array< Tp, N > &rhs)
Definition: stl.hpp:367
Lhs operator/(Lhs, const Rhs &)
Definition: stl.hpp:310
Lhs operator*(Lhs, const Rhs &)
Definition: stl.hpp:295
std::array< Tp, N > & operator*=(std::array< Tp, N > &, const std::array< Tp, N > &)
Definition: stl.hpp:134
std::array< Tp, N > & operator-=(std::array< Tp, N > &, const std::array< Tp, N > &)
Definition: stl.hpp:96
std::array< Tp, N > operator+(std::array< Tp, N > lhs, const std::array< Tp, N > &rhs)
Definition: stl.hpp:323
Definition: kokkosp.cpp:39