1 // Copyright 2021 The Pigweed Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 // use this file except in compliance with the License. You may obtain a copy of 5 // the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations under 13 // the License. 14 15 #include <array> 16 #include <cstddef> 17 18 namespace { 19 20 int volatile* unoptimizable; 21 22 template <typename Callable> 23 class CallableSize { 24 public: CallableSize(Callable callable)25 constexpr CallableSize(Callable callable) : callable_(std::move(callable)) {} 26 PreventOptimization()27 int PreventOptimization() { return *unoptimizable; } 28 29 private: 30 alignas(std::max_align_t) Callable callable_; 31 }; 32 Function()33[[maybe_unused]] void Function() {} 34 35 class CustomCallableClass { 36 public: operator ()()37 void operator()() {} 38 39 private: 40 [[maybe_unused]] std::array<std::byte, 16> data_; 41 }; 42 43 } // namespace 44 main()45int main() { 46 int a = 0; 47 int b = 1; 48 int c = 2; 49 int d = 3; 50 static_cast<void>(a); 51 static_cast<void>(b); 52 static_cast<void>(c); 53 static_cast<void>(d); 54 55 #if defined(_BASE) 56 CallableSize<std::array<std::byte, 0>> callable_size({}); 57 #elif defined(_FUNCTION_POINTER) 58 static CallableSize callable_size(Function); 59 #elif defined(_STATIC_LAMBDA) 60 static CallableSize callable_size(+[]() {}); 61 #elif defined(_SIMPLE_LAMBDA) 62 static CallableSize callable_size([]() {}); 63 #elif defined(_CAPTURING_LAMBDA) 64 static CallableSize callable_size([a]() { static_cast<void>(a); }); 65 #elif defined(_MULTI_CAPTURING_LAMBDA) 66 static CallableSize callable_size([a, b, c, d]() { 67 static_cast<void>(a); 68 static_cast<void>(b); 69 static_cast<void>(c); 70 static_cast<void>(d); 71 }); 72 #elif defined(_CUSTOM_CLASS) 73 static CallableSize callable_size((CustomCallableClass())); 74 #endif 75 76 int foo = callable_size.PreventOptimization(); 77 return sizeof(callable_size) + foo; 78 } 79