libtcspc C++ API
Streaming TCSPC and time tag data processing
Loading...
Searching...
No Matches
common.hpp
1/*
2 * This file is part of libtcspc
3 * Copyright 2019-2026 Board of Regents of the University of Wisconsin System
4 * SPDX-License-Identifier: MIT
5 */
6
7#pragma once
8
9#include <cassert>
10#include <concepts>
11#include <cstdint>
12#include <type_traits>
13
14namespace tcspc::internal {
15
16// Disable inlining; Must be placed _after_ standard attributes such as
17// [[noreturn]], for MSVC.
18#if defined(__GNUC__)
19#define LIBTCSPC_NOINLINE [[gnu::noinline]]
20#elif defined(_MSC_VER)
21#define LIBTCSPC_NOINLINE [[msvc::noinline]]
22#else
23#define LIBTCSPC_NOINLINE
24#endif
25
26// Run-time check for actual alignment.
27template <typename T>
28inline auto is_aligned(void const *ptr) noexcept -> bool {
29 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
30 auto const start = reinterpret_cast<uintptr_t>(ptr);
31 return start % alignof(T) == 0;
32}
33
34// C++23 std::unreachable(), but safe in debug build.
35[[noreturn]] inline void unreachable() {
36 assert(false);
37#if defined(__GNUC__)
38 __builtin_unreachable();
39#elif defined(_MSC_VER)
40 __assume(false);
41#endif
42}
43
44// A "false" template metafunction that can be used with static_assert in
45// constexpr-if branches (by pretending that it may not always be false).
46template <typename T> struct always_false : std::false_type {};
47
48template <typename T>
49inline constexpr bool always_false_v = always_false<T>::value;
50
51template <typename T, typename... U>
52concept same_as_any_of = (std::same_as<T, U> || ...);
53
54// Overloaded idiom for std::visit
55template <typename... Ts> struct overloaded : Ts... {
56 using Ts::operator()...;
57};
58template <typename... Ts> overloaded(Ts...) -> overloaded<Ts...>;
59
60} // namespace tcspc::internal