| // Copyright (C) 2018 The Android Open Source Project |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #include <ostream> |
| |
| namespace iorap { |
| |
| // kIsDebugBuild is special. |
| // It gets to be in the 'iorap' namespace |
| // so that different modules don't need to qualify it. |
| #ifndef NDEBUG |
| static constexpr bool kIsDebugBuild = true; |
| #else |
| static constexpr bool kIsDebugBuild = false; |
| #endif |
| |
| namespace common { |
| |
| // TODO: move below code to helpers. |
| template <typename T, bool> |
| struct base_if_condition {}; |
| |
| template <typename T> |
| struct base_if_condition<T, true> : public T {}; |
| |
| template <typename T> |
| using base_if_debug = base_if_condition<T, kIsDebugBuild>; |
| |
| namespace detail { |
| // "if constexpr" doesn't allow us to exclude fields from a struct/class, |
| // and also "if constexpr" doesn't allow us to reference a field that does not |
| // exist. |
| // so we must move everything into a separate base class. |
| template <bool kIsDebug = kIsDebugBuild> |
| struct DebugCounterBase { |
| constexpr size_t value() const { |
| return counter; |
| } |
| |
| constexpr void set_value(size_t value) { |
| counter = value; |
| } |
| |
| size_t counter{1}; // Don't start with 0. |
| }; |
| |
| template <> |
| struct DebugCounterBase<false /*kIsDebug*/> { |
| constexpr size_t value() const { |
| return 0; |
| } |
| |
| constexpr void set_value(size_t value) { |
| } |
| }; |
| } // namespace detail |
| |
| // This counter does absolutely nothing, the code compiles to no-ops |
| // when debugging is disabled. |
| struct DebugCounter : detail::DebugCounterBase<> { |
| constexpr DebugCounter& operator++() { |
| set_value(value() + 1); |
| return *this; |
| } |
| |
| constexpr DebugCounter operator++(int) { |
| DebugCounter now = *this; |
| set_value(value() + 1); |
| return now; |
| } |
| |
| constexpr operator size_t() const { |
| return value(); |
| } |
| |
| friend std::ostream& operator<<(std::ostream& os, DebugCounter counter); |
| }; |
| |
| inline std::ostream& operator<<(std::ostream& os, DebugCounter counter) { |
| os << counter.value(); |
| return os; |
| } |
| |
| // TODO: refactor DebugCounter and base traits into their own files? |
| |
| } // namespace common |
| } // namespace iorap |