Lumiera  0.pre.03
»edit your freedom«
microbenchmark-adaptor.hpp
Go to the documentation of this file.
1 /*
2  MICROBENCHMARK-ADAPTOR.hpp - helper to support microbenchmarks
3 
4  Copyright (C) Lumiera.org
5  2023, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 */
22 
23 
39 #ifndef LIB_TEST_MICROBENCHMARK_ADAPTOR_H
40 #define LIB_TEST_MICROBENCHMARK_ADAPTOR_H
41 
42 
43 #include "lib/meta/function.hpp"
44 #include "lib/meta/util.hpp"
45 
46 namespace lib {
47 namespace test{
48 namespace microbenchmark {
49 
51  using std::is_arithmetic;
52  using std::is_same;
53  using std::__and_;
54  using std::__not_;
55 
56 
61  template<class SIG, typename SEL=void>
62  struct Adaptor
63  {
64  static_assert (not sizeof(SIG), "Unable to adapt given functor.");
65  };
66 
67  template<>
68  struct Adaptor<size_t(size_t)>
69  {
70  template<typename FUN>
71  static decltype(auto)
72  wrap (FUN&& fun)
73  {
74  return std::forward<FUN>(fun);
75  }
76  };
77 
78  template<>
79  struct Adaptor<void(void)>
80  {
81  template<typename FUN>
82  static auto
83  wrap (FUN&& fun)
84  {
85  return [functor=std::forward<FUN>(fun)]
86  (size_t)
87  {
88  functor();
89  return size_t(1);
90  };
91  }
92  };
93 
94  template<typename ON, typename IN>
95  struct Adaptor<ON(IN), enable_if<__and_<is_arithmetic<IN>, __not_<is_same<IN,size_t>>
96  ,is_arithmetic<ON>, __not_<is_same<ON,size_t>>
97  >>>
98  {
99  template<typename FUN>
100  static auto
101  wrap (FUN&& fun)
102  {
103  return [functor=std::forward<FUN>(fun)]
104  (size_t i)
105  {
106  return size_t(functor(i));
107  };
108  }
109  };
110 
111  template<typename ON>
112  struct Adaptor<ON(void), enable_if<__and_<is_arithmetic<ON>, __not_<is_same<ON,size_t>>
113  >>>
114  {
115  template<typename FUN>
116  static auto
117  wrap (FUN&& fun)
118  {
119  return [functor=std::forward<FUN>(fun)]
120  (size_t)
121  {
122  return size_t(functor());
123  };
124  }
125  };
126 
127  template<typename IN>
128  struct Adaptor<void(IN), enable_if<__and_<is_arithmetic<IN>, __not_<is_same<IN,size_t>>
129  >>>
130  {
131  template<typename FUN>
132  static auto
133  wrap (FUN&& fun)
134  {
135  return [functor=std::forward<FUN>(fun)]
136  (size_t i)
137  {
138  functor(i);
139  return size_t(1);
140  };
141  }
142  };
143 
144 
145 
156  template<typename FUN>
157  inline decltype(auto)
158  adapted4benchmark (FUN&& fun)
159  {
160  static_assert (lib::meta::_Fun<FUN>(), "Need something function-like.");
161  static_assert (lib::meta::_Fun<FUN>::ARITY <=1, "Function with zero or one argument required.");
162 
163  using Sig = typename lib::meta::_Fun<FUN>::Sig;
164 
165  return Adaptor<Sig>::wrap (std::forward<FUN> (fun));
166  }
167 
168 
169 
170 }}} // namespace lib::test::microbenchmark
171 #endif /*LIB_TEST_MICROBENCHMARK_ADAPTOR_H*/
Definition: run.hpp:49
Simple and lightweight helpers for metaprogramming and type detection.
Implementation namespace for support and library code.
typename enable_if_c< Cond::value, T >::type enable_if
SFINAE helper to control the visibility of specialisations and overloads.
Definition: meta/util.hpp:92
Metaprogramming tools for transforming functor types.