Механизм счётчика на этапе компиляции, основанный на перегрузке функций и ADL.
#include <scl/utility/preprocessor/counter.h>Содержание:
SCL_COUNTER_VALUE(Tag)Считывает текущее значение счётчика времени компиляции, идентифицируемого тегом Tag.
#include <scl/utility/preprocessor/counter.h>#define SCL_COUNTER_VALUE(Tag) /* ... */Counter<int> и Counter<float> независимы).constexpr типа std::uint_fast32_t.SCL_COUNTER_NEXT для данного тега.#include <scl/utility/preprocessor/counter.h>
struct MyTag {};
constexpr auto v0 = SCL_COUNTER_VALUE(MyTag);
static_assert(v0 == 0);
SCL_COUNTER_NEXT(MyTag)
constexpr auto v1 = SCL_COUNTER_VALUE(MyTag);
static_assert(v1 == 1);
SCL_COUNTER_NEXT(Tag)Инкрементирует счётчик времени компиляции, идентифицируемый тегом Tag.
#include <scl/utility/preprocessor/counter.h>#define SCL_COUNTER_NEXT(Tag) /* ... */scl::preprocessor::detail, которая заставляет последующие вызовы SCL_COUNTER_VALUE(Tag) возвращать увеличенное значение.#include <scl/utility/preprocessor/counter.h>
struct TagA {};
struct TagB {};
// Два независимых счётчика
constexpr auto a0 = SCL_COUNTER_VALUE(TagA); // 0
constexpr auto b0 = SCL_COUNTER_VALUE(TagB); // 0
SCL_COUNTER_NEXT(TagA)
constexpr auto a1 = SCL_COUNTER_VALUE(TagA); // 1
constexpr auto b1 = SCL_COUNTER_VALUE(TagB); // по-прежнему 0
SCL_COUNTER_NEXT(TagA)
SCL_COUNTER_NEXT(TagB)
constexpr auto a2 = SCL_COUNTER_VALUE(TagA); // 2
constexpr auto b2 = SCL_COUNTER_VALUE(TagB); // 1
#include <scl/utility/preprocessor/counter.h>
template <typename T>
struct TypeCounter {};
constexpr auto int_v0 = SCL_COUNTER_VALUE(TypeCounter<int>);
static_assert(int_v0 == 0);
SCL_COUNTER_NEXT(TypeCounter<int>)
constexpr auto int_v1 = SCL_COUNTER_VALUE(TypeCounter<int>);
static_assert(int_v1 == 1);
// Другая специализация — отдельный счётчик
constexpr auto float_v0 = SCL_COUNTER_VALUE(TypeCounter<float>);
static_assert(float_v0 == 0);
SCL_FORWARD используется внутри для обработки шаблонных тегов, содержащих запятые.