1 /*
2 * Copyright © 2020 Christian Persch
3 *
4 * This library is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published
6 * by the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this library. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18 #pragma once
19
20 #include <algorithm>
21 #include <exception>
22 #include <type_traits>
23 #include <memory>
24
25 namespace vte {
26
27 // This is like std::clamp, except that it doesn't throw when
28 // max_v<min_v, but instead returns min_v in that case.
29 template<typename T>
30 constexpr inline T const&
clamp(T const & v,T const & min_v,T const & max_v)31 clamp(T const& v,
32 T const& min_v,
33 T const& max_v)
34 {
35 return std::max(std::min(v, max_v), min_v);
36 }
37
38 // Converts from E to the underlying integral type, where E is an enum
39 // with integral underlying type.
40 template<typename E>
to_integral(E e)41 inline constexpr auto to_integral(E e) noexcept
42 -> std::enable_if_t<std::is_enum_v<E> &&
43 std::is_integral_v<std::underlying_type_t<E>>,
44 std::underlying_type_t<E>>
45 {
46 return static_cast<std::underlying_type_t<E>>(e);
47 }
48
49 #ifdef VTE_DEBUG
50 void log_exception(char const* func = __builtin_FUNCTION(),
51 char const* filename = __builtin_FILE(),
52 int const line = __builtin_LINE()) noexcept;
53 #else
log_exception()54 inline void log_exception() noexcept { }
55 #endif
56
57 template <typename T, typename D, D func>
58 class FreeablePtrDeleter {
59 public:
operator ()(T * obj) const60 void operator()(T* obj) const
61 {
62 if (obj)
63 func(obj);
64 }
65 };
66
67 template <typename T, typename D, D func>
68 using FreeablePtr = std::unique_ptr<T, FreeablePtrDeleter<T, D, func>>;
69
70 } // namespace vte
71