Coverage Report

Created: 2025-04-27 06:20

/src/LPM/external.protobuf/include/google/protobuf/has_bits.h
Line
Count
Source (jump to first uncovered line)
1
// Protocol Buffers - Google's data interchange format
2
// Copyright 2008 Google Inc.  All rights reserved.
3
//
4
// Use of this source code is governed by a BSD-style
5
// license that can be found in the LICENSE file or at
6
// https://developers.google.com/open-source/licenses/bsd
7
8
#ifndef GOOGLE_PROTOBUF_HAS_BITS_H__
9
#define GOOGLE_PROTOBUF_HAS_BITS_H__
10
11
#include <cassert>
12
#include <cstddef>
13
#include <cstdint>
14
#include <cstring>
15
#include <initializer_list>
16
17
// Must be included last.
18
#include "google/protobuf/port_def.inc"
19
20
#ifdef SWIG
21
#error "You cannot SWIG proto headers"
22
#endif
23
24
namespace google {
25
namespace protobuf {
26
namespace internal {
27
28
template <int doublewords>
29
class HasBits {
30
 public:
31
51
  PROTOBUF_NDEBUG_INLINE constexpr HasBits() : has_bits_{} {}
32
33
  constexpr HasBits(std::initializer_list<uint32_t> has_bits) : has_bits_{} {
34
    Copy(has_bits_, &*has_bits.begin(), has_bits.size());
35
  }
36
37
102
  PROTOBUF_NDEBUG_INLINE void Clear() {
38
102
    memset(has_bits_, 0, sizeof(has_bits_));
39
102
  }
40
41
102
  PROTOBUF_NDEBUG_INLINE uint32_t& operator[](int index) {
42
102
    return has_bits_[index];
43
102
  }
44
45
0
  PROTOBUF_NDEBUG_INLINE const uint32_t& operator[](int index) const {
46
0
    return has_bits_[index];
47
0
  }
48
49
  bool operator==(const HasBits<doublewords>& rhs) const {
50
    return memcmp(has_bits_, rhs.has_bits_, sizeof(has_bits_)) == 0;
51
  }
52
53
  bool operator!=(const HasBits<doublewords>& rhs) const {
54
    return !(*this == rhs);
55
  }
56
57
  void Or(const HasBits<doublewords>& rhs) {
58
    for (int i = 0; (i + 1) < doublewords; i += 2) {
59
      Write64B(Read64B(i) | rhs.Read64B(i), i);
60
    }
61
    if ((doublewords % 2) != 0) {
62
      has_bits_[doublewords - 1] |= rhs.has_bits_[doublewords - 1];
63
    }
64
  }
65
66
  bool empty() const;
67
68
 private:
69
  // Unfortunately, older GCC compilers (and perhaps others) fail on initializer
70
  // arguments for an std::array<> or any type of array constructor. Below is a
71
  // handrolled constexpr 'Copy' function that we use to make a constexpr
72
  // constructor that accepts a `std::initializer` list.
73
  static inline constexpr void Copy(uint32_t* dst, const uint32_t* src,
74
                                    size_t n) {
75
    assert(n <= doublewords);
76
    for (size_t ix = 0; ix < n; ++ix) {
77
      dst[ix] = src[ix];
78
    }
79
    for (size_t ix = n; ix < doublewords; ++ix) {
80
      dst[ix] = 0;
81
    }
82
  }
83
84
  uint64_t Read64B(int index) const {
85
    uint64_t v;
86
    memcpy(&v, has_bits_ + index, sizeof(v));
87
    return v;
88
  }
89
90
  void Write64B(uint64_t v, int index) {
91
    memcpy(has_bits_ + index, &v, sizeof(v));
92
  }
93
94
  uint32_t has_bits_[doublewords];
95
};
96
97
template <>
98
0
inline bool HasBits<1>::empty() const {
99
0
  return !has_bits_[0];
100
0
}
101
102
template <>
103
0
inline bool HasBits<2>::empty() const {
104
0
  return !(has_bits_[0] | has_bits_[1]);
105
0
}
106
107
template <>
108
0
inline bool HasBits<3>::empty() const {
109
0
  return !(has_bits_[0] | has_bits_[1] | has_bits_[2]);
110
0
}
111
112
template <>
113
0
inline bool HasBits<4>::empty() const {
114
0
  return !(has_bits_[0] | has_bits_[1] | has_bits_[2] | has_bits_[3]);
115
0
}
116
117
template <int doublewords>
118
inline bool HasBits<doublewords>::empty() const {
119
  for (uint32_t bits : has_bits_) {
120
    if (bits) return false;
121
  }
122
  return true;
123
}
124
125
}  // namespace internal
126
}  // namespace protobuf
127
}  // namespace google
128
129
#include "google/protobuf/port_undef.inc"
130
131
#endif  // GOOGLE_PROTOBUF_HAS_BITS_H__