// 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
|