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