OpenVPN 3 Core Library
Loading...
Searching...
No Matches
ffs.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) 2012- OpenVPN Inc.
8//
9// SPDX-License-Identifier: MPL-2.0 OR AGPL-3.0-only WITH openvpn3-openssl-exception
10//
11
12#ifndef OPENVPN_COMMON_FFS_H
13#define OPENVPN_COMMON_FFS_H
14
15// find_first_set: find the one-based position of the first 1 bit in
16// a word (scanning from least significant bit to most significant)
17
18// find_last_set: find the one-based position of the last 1 bit in
19// a word (scanning from most significant bit to least significant)
20
21namespace openvpn {
22
23#if defined(__GNUC__)
24
25template <typename T>
26inline constexpr int n_bits_type()
27{
28 return sizeof(T) * 8;
29}
30
31template <typename T>
32inline constexpr int n_bits_type(const T &v)
33{
34 return sizeof(v) * 8;
35}
36
37inline int find_first_set(const unsigned int v)
38{
39 if (!v)
40 return 0;
41 return __builtin_ffs(v);
42}
43
44inline int find_first_set(const int v)
45{
46 return find_first_set(static_cast<unsigned int>(v));
47}
48
49inline int find_last_set(const unsigned int v)
50{
51 if (!v)
52 return 0;
53 return n_bits_type(v) - __builtin_clz(v);
54}
55
56inline int find_last_set(const int v)
57{
58 return find_last_set(static_cast<unsigned int>(v));
59}
60
61inline int find_first_set(const unsigned long v)
62{
63 if (!v)
64 return 0;
65 return __builtin_ffsl(v);
66}
67
68inline int find_first_set(const long v)
69{
70 return find_first_set(static_cast<unsigned long>(v));
71}
72
73inline int find_last_set(const unsigned long v)
74{
75 if (!v)
76 return 0;
77 return n_bits_type(v) - __builtin_clzl(v);
78}
79
80inline int find_last_set(const long v)
81{
82 return find_last_set(static_cast<unsigned long>(v));
83}
84
85inline int find_first_set(const unsigned long long v)
86{
87 if (!v)
88 return 0;
89 return __builtin_ffsll(v);
90}
91
92inline int find_first_set(const long long v)
93{
94 return find_first_set(static_cast<unsigned long long>(v));
95}
96
97inline int find_last_set(const unsigned long long v)
98{
99 if (!v)
100 return 0;
101 return n_bits_type(v) - __builtin_clzll(v);
102}
103
104inline int find_last_set(const long long v)
105{
106 return find_last_set(static_cast<unsigned long long>(v));
107}
108
109#elif defined(_MSC_VER)
110
111#include <intrin.h>
112
113inline int find_first_set(unsigned int x)
114{
115 if (!x)
116 return 0;
117 unsigned int r = 0;
118 _BitScanForward((unsigned long *)&r, x);
119 return r + 1;
120}
121
122inline int find_last_set(unsigned int x)
123{
124 if (!x)
125 return 0;
126 unsigned int r = 0;
127 _BitScanReverse((unsigned long *)&r, x);
128 return r + 1;
129}
130
131#else
132#error no find_first_set / find_last_set implementation for this platform
133#endif
134
135template <typename T>
136inline bool is_pow2(const T v)
137{
138 return v && find_first_set(v) == find_last_set(v);
139}
140
141template <typename T>
142inline int log2(const T v)
143{
144 return find_last_set(v) - 1;
145}
146
147} // namespace openvpn
148
149#endif // OPENVPN_COMMON_FFS_H
Support deferred server-side state creation when client connects.
Definition ovpncli.cpp:95
int log2(const T v)
Definition ffs.hpp:142
bool is_pow2(const T v)
Definition ffs.hpp:136