OpenVPN 3 Core Library
Loading...
Searching...
No Matches
clamp_typerange.hpp
Go to the documentation of this file.
1// OpenVPN -- An application to securely tunnel IP networks
2// over a single port, with support for SSL/TLS-based
3// session authentication and key exchange,
4// packet encryption, packet authentication, and
5// packet compression.
6//
7// Copyright (C) 2023- OpenVPN Inc.
8//
9// SPDX-License-Identifier: MPL-2.0 OR AGPL-3.0-only WITH openvpn3-openssl-exception
10//
11
12
13
14#pragma once
15
16#include <limits>
17#include <algorithm>
18#include <functional>
19
20#include "numeric_util.hpp"
21
23
24/* ============================================================================================================= */
25// clamp_to_typerange
26/* ============================================================================================================= */
27
36template <typename OutT, typename InT>
37OutT clamp_to_typerange(InT inVal)
38{
39 if constexpr (numeric_util::is_int_rangesafe<OutT, InT>())
40 {
41 return static_cast<OutT>(inVal);
42 }
43 else if constexpr (numeric_util::is_int_u2s<OutT, InT>())
44 {
45 auto unsignedInVal = static_cast<uintmax_t>(inVal);
46 return static_cast<OutT>(std::min(static_cast<uintmax_t>(std::numeric_limits<OutT>::max()), unsignedInVal));
47 }
48 else if constexpr (numeric_util::is_int_s2u<OutT, InT>())
49 {
50 auto lowerVal = static_cast<uintmax_t>(std::max(inVal, 0));
51 auto upperLimit = static_cast<uintmax_t>(std::numeric_limits<OutT>::max());
52 return static_cast<OutT>(std::min(lowerVal, upperLimit));
53 }
54 else
55 {
56 auto outMin = static_cast<InT>(std::numeric_limits<OutT>::min());
57 auto outMax = static_cast<InT>(std::numeric_limits<OutT>::max());
58 return static_cast<OutT>(std::clamp(inVal, outMin, outMax));
59 }
60}
61
62/* ============================================================================================================= */
63// clamp_to_default
64/* ============================================================================================================= */
65
76template <typename OutT, typename InT>
77OutT clamp_to_default(InT inVal, OutT defVal)
78{
79 if constexpr (!numeric_util::is_int_rangesafe<OutT, InT>())
80 {
81 if (!is_safe_conversion<OutT>(inVal))
82 return defVal;
83 }
84
85 return static_cast<OutT>(inVal);
86}
87
88/* ============================================================================================================= */
89// clamp_notify
90/* ============================================================================================================= */
91
103template <typename OutT, typename InT, typename FuncT>
104OutT clamp_notify(InT inVal, FuncT cb)
105{
106 if constexpr (!numeric_util::is_int_rangesafe<OutT, InT>())
107 {
108 if (!is_safe_conversion<OutT>(inVal))
109 return std::invoke(cb, inVal);
110 }
111
112 return static_cast<OutT>(inVal);
113}
114
115} // namespace openvpn::numeric_util
OutT clamp_to_typerange(InT inVal)
Clamps the input value to the legal range for the output type.
OutT clamp_notify(InT inVal, FuncT cb)
Calls FuncT cb if the input value exceeds the range of the output type.
OutT clamp_to_default(InT inVal, OutT defVal)
Adjusts the input value to the default if the input value exceeds the range of the output type.