detail/utils.hpp
1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION.
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 #pragma once
6 
7 #include <cstring>
8 #include <exception>
9 #include <utility>
10 
11 #include <kvikio/error.hpp>
12 
13 namespace kvikio::detail {
14 
22 [[nodiscard]] std::size_t align_up(std::size_t value, std::size_t alignment);
23 
31 [[nodiscard]] void* align_up(void* addr, std::size_t alignment);
32 
40 [[nodiscard]] std::size_t align_down(std::size_t value, std::size_t alignment);
41 
49 [[nodiscard]] void* align_down(void* addr, std::size_t alignment);
50 
58 bool is_aligned(std::size_t value, std::size_t alignment);
59 
67 bool is_aligned(void* addr, std::size_t alignment);
68 
85 template <typename F>
86 class ScopeExit {
87  static_assert(std::is_invocable_v<F>, "ScopeExit callable must be invocable with no arguments");
88 
89  private:
90  F _cleanup;
91 
92  public:
97  [[nodiscard]] explicit ScopeExit(F&& cleanup) : _cleanup(std::move(cleanup)) {}
98 
99  ~ScopeExit() noexcept
100  {
101  try {
102  _cleanup();
103  } catch (std::exception const& e) {
104  KVIKIO_LOG_ERROR(e.what());
105  } catch (...) {
106  KVIKIO_LOG_ERROR("Unhandled exception");
107  }
108  }
109 
110  ScopeExit(ScopeExit const&) = delete;
111  ScopeExit& operator=(ScopeExit const&) = delete;
112  ScopeExit(ScopeExit&&) = delete;
113  ScopeExit& operator=(ScopeExit&&) = delete;
114 };
115 
116 } // namespace kvikio::detail
A simple scope guard that invokes a cleanup callable upon destruction.
ScopeExit(F &&cleanup)
Constructs a scope guard that will invoke cleanup on destruction.