Skip to content

Commit ad1e976

Browse files
ClaytonKnittelcopybara-github
authored andcommitted
Move RepeatedFieldTraits to a separate header.
Future changes will introduce other targets that will need `RepeatedFieldTraits` but can't depend directly on `repeated_field_proxy`. Note that the `repeated_field_traits` target has private visibility. PiperOrigin-RevId: 892495704
1 parent 3bf2b07 commit ad1e976

File tree

4 files changed

+124
-87
lines changed

4 files changed

+124
-87
lines changed

cmake/installed_include_golden.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ google/protobuf/reflection_visit_field_info.h
113113
google/protobuf/reflection_visit_fields.h
114114
google/protobuf/repeated_field.h
115115
google/protobuf/repeated_field_proxy.h
116+
google/protobuf/repeated_field_proxy_traits.h
116117
google/protobuf/repeated_ptr_field.h
117118
google/protobuf/runtime_version.h
118119
google/protobuf/serial_arena.h

src/google/protobuf/BUILD.bazel

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -965,7 +965,7 @@ cc_library(
965965
deps = [
966966
":port",
967967
":protobuf_lite",
968-
"@abseil-cpp//absl/base:no_destructor",
968+
":repeated_field_proxy_traits",
969969
"@abseil-cpp//absl/log:absl_check",
970970
"@abseil-cpp//absl/strings:cord",
971971
"@abseil-cpp//absl/strings:string_view",
@@ -996,6 +996,17 @@ cc_test(
996996
],
997997
)
998998

999+
cc_library(
1000+
name = "repeated_field_proxy_traits",
1001+
hdrs = ["repeated_field_proxy_traits.h"],
1002+
strip_include_prefix = "/src",
1003+
deps = [
1004+
":protobuf_lite",
1005+
"@abseil-cpp//absl/strings:cord",
1006+
"@abseil-cpp//absl/strings:string_view",
1007+
],
1008+
)
1009+
9991010
# This provides just the header files for use in projects that need to build
10001011
# shared libraries for dynamic loading. This target is available until Bazel
10011012
# adds native support for such use cases.

src/google/protobuf/repeated_field_proxy.h

Lines changed: 1 addition & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "absl/strings/cord.h"
1212
#include "absl/strings/string_view.h"
1313
#include "google/protobuf/repeated_field.h"
14+
#include "google/protobuf/repeated_field_proxy_traits.h"
1415
#include "google/protobuf/repeated_ptr_field.h"
1516

1617

@@ -28,31 +29,6 @@ namespace internal {
2829
template <typename ElementType>
2930
class RepeatedFieldProxyInternalPrivateAccessHelper;
3031

31-
// A type trait to determine if a repeated field element of type `ElementType`
32-
// is a string type.
33-
template <typename ElementType>
34-
static constexpr bool RepeatedElementTypeIsString =
35-
std::is_same_v<ElementType, std::string> ||
36-
std::is_same_v<ElementType, absl::string_view> ||
37-
std::is_same_v<ElementType, absl::Cord>;
38-
39-
// A type trait to determine if a repeated field element of type `ElementType`
40-
// is a message type.
41-
//
42-
// We would like to use `std::is_base_of_v<MessageLite, ElementType>` to
43-
// determine if `ElementType` is a message type, but that requires `ElementType`
44-
// to be complete. In contexts where `ElementType` is not complete, such as
45-
// generated protobuf source files/headers that forward declare external types,
46-
// we only have the forward declaration of `ElementType`.
47-
//
48-
// Aside from strings, all element types other than messages are primitive
49-
// types. Enums may be incomplete, but they are forward declared as `enum
50-
// <EnumName> : int;`. We therefore can distinguish incomplete message elements
51-
// with `std::is_class_v`.
52-
template <typename ElementType>
53-
static constexpr bool RepeatedElementTypeIsMessage =
54-
std::is_class_v<ElementType> && !RepeatedElementTypeIsString<ElementType>;
55-
5632
namespace string_util {
5733

5834
template <typename StringType, typename T>
@@ -100,67 +76,6 @@ inline void SetElement(absl::Cord& element, T&& value) {
10076

10177
} // namespace string_util
10278

103-
// RepeatedFieldTraits is a type trait that maps an element type to the concrete
104-
// container type that will back the repeated field in the containing message.
105-
// This is currently either `RepeatedField` or `RepeatedPtrField`.
106-
//
107-
// Note that message and string types are specialized below this base template.
108-
template <typename ElementType, typename Enable = void>
109-
struct RepeatedFieldTraits {
110-
static_assert(!std::is_const_v<ElementType>);
111-
// The default specialization is only for primitive types. Messages and
112-
// strings are specialized below.
113-
static_assert(std::is_integral_v<ElementType> ||
114-
std::is_floating_point_v<ElementType>);
115-
116-
using type = RepeatedField<ElementType>;
117-
using const_reference = ElementType;
118-
using reference = ElementType;
119-
using const_iterator = typename type::const_iterator;
120-
using iterator = typename type::iterator;
121-
};
122-
123-
// Specialization for message types.
124-
template <typename ElementType>
125-
struct RepeatedFieldTraits<
126-
ElementType, std::enable_if_t<RepeatedElementTypeIsMessage<ElementType>>> {
127-
static_assert(!std::is_const_v<ElementType>);
128-
129-
using type = RepeatedPtrField<ElementType>;
130-
using const_reference = const ElementType&;
131-
using reference = ElementType&;
132-
using const_iterator = typename type::const_iterator;
133-
using iterator = typename type::iterator;
134-
};
135-
136-
// Explicit specializations for string types.
137-
template <>
138-
struct RepeatedFieldTraits<absl::string_view> {
139-
using type = RepeatedPtrField<std::string>;
140-
using const_reference = absl::string_view;
141-
using reference = absl::string_view;
142-
using const_iterator = RepeatedPtrIterator<const absl::string_view>;
143-
using iterator = RepeatedPtrIterator<absl::string_view>;
144-
};
145-
146-
template <>
147-
struct RepeatedFieldTraits<std::string> {
148-
using type = RepeatedPtrField<std::string>;
149-
using const_reference = const std::string&;
150-
using reference = std::string&;
151-
using const_iterator = typename type::const_iterator;
152-
using iterator = typename type::iterator;
153-
};
154-
155-
template <>
156-
struct RepeatedFieldTraits<absl::Cord> {
157-
using type = RepeatedField<absl::Cord>;
158-
using const_reference = const absl::Cord&;
159-
using reference = absl::Cord&;
160-
using const_iterator = typename type::const_iterator;
161-
using iterator = typename type::iterator;
162-
};
163-
16479
// The base class for both mutable and const repeated field proxies. Implements
16580
// all of the common methods and dependent types for both classes.
16681
template <typename ElementType>
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
#ifndef GOOGLE_PROTOBUF_REPEATED_FIELD_PROXY_TRAITS_H__
2+
#define GOOGLE_PROTOBUF_REPEATED_FIELD_PROXY_TRAITS_H__
3+
4+
#include <string>
5+
#include <type_traits>
6+
7+
#include "absl/strings/cord.h"
8+
#include "absl/strings/string_view.h"
9+
#include "google/protobuf/repeated_field.h"
10+
#include "google/protobuf/repeated_ptr_field.h"
11+
12+
13+
namespace google {
14+
namespace protobuf {
15+
namespace internal {
16+
17+
template <typename ElementType>
18+
static constexpr bool RepeatedElementTypeIsPrimitive =
19+
std::is_integral_v<ElementType> || std::is_floating_point_v<ElementType>;
20+
21+
// A type trait to determine if a repeated field element of type `ElementType`
22+
// is a string type.
23+
template <typename ElementType>
24+
static constexpr bool RepeatedElementTypeIsString =
25+
std::is_same_v<ElementType, std::string> ||
26+
std::is_same_v<ElementType, absl::string_view> ||
27+
std::is_same_v<ElementType, absl::Cord>;
28+
29+
// A type trait to determine if a repeated field element of type `ElementType`
30+
// is a message type.
31+
//
32+
// We would like to use `std::is_base_of_v<MessageLite, ElementType>` to
33+
// determine if `ElementType` is a message type, but that requires `ElementType`
34+
// to be complete. In contexts where `ElementType` is not complete, such as
35+
// generated protobuf source files/headers that forward declare external types,
36+
// we only have the forward declaration of `ElementType`.
37+
//
38+
// Aside from strings, all element types other than messages are primitive
39+
// types. Enums may be incomplete, but they are forward declared as `enum
40+
// <EnumName> : int;`. We therefore can distinguish incomplete message elements
41+
// with `std::is_class_v`.
42+
template <typename ElementType>
43+
static constexpr bool RepeatedElementTypeIsMessage =
44+
std::is_class_v<ElementType> && !RepeatedElementTypeIsString<ElementType>;
45+
46+
// RepeatedFieldTraits is a type trait that maps an element type to the concrete
47+
// container type that will back the repeated field in the containing message.
48+
// This is currently either `RepeatedField` or `RepeatedPtrField`.
49+
//
50+
// Note that message and string types are specialized below this base template.
51+
template <typename ElementType, typename Enable = void>
52+
struct RepeatedFieldTraits {
53+
static_assert(!std::is_const_v<ElementType>);
54+
// The default specialization is only for primitive types. Messages and
55+
// strings are specialized below.
56+
static_assert(RepeatedElementTypeIsPrimitive<ElementType>);
57+
58+
using type = ::google::protobuf::RepeatedField<ElementType>;
59+
using const_reference = ElementType;
60+
using reference = ElementType;
61+
using const_iterator = typename type::const_iterator;
62+
using iterator = typename type::iterator;
63+
};
64+
65+
// Specialization for message types.
66+
template <typename ElementType>
67+
struct RepeatedFieldTraits<
68+
ElementType, std::enable_if_t<RepeatedElementTypeIsMessage<ElementType>>> {
69+
static_assert(!std::is_const_v<ElementType>);
70+
71+
using type = ::google::protobuf::RepeatedPtrField<ElementType>;
72+
using const_reference = const ElementType&;
73+
using reference = ElementType&;
74+
using const_iterator = typename type::const_iterator;
75+
using iterator = typename type::iterator;
76+
};
77+
78+
// Explicit specializations for string types.
79+
template <>
80+
struct RepeatedFieldTraits<absl::string_view> {
81+
using type = ::google::protobuf::RepeatedPtrField<std::string>;
82+
using const_reference = absl::string_view;
83+
using reference = absl::string_view;
84+
using const_iterator = RepeatedPtrIterator<const absl::string_view>;
85+
using iterator = RepeatedPtrIterator<absl::string_view>;
86+
};
87+
88+
template <>
89+
struct RepeatedFieldTraits<std::string> {
90+
using type = ::google::protobuf::RepeatedPtrField<std::string>;
91+
using const_reference = const std::string&;
92+
using reference = std::string&;
93+
using const_iterator = typename type::const_iterator;
94+
using iterator = typename type::iterator;
95+
};
96+
97+
template <>
98+
struct RepeatedFieldTraits<absl::Cord> {
99+
using type = ::google::protobuf::RepeatedField<absl::Cord>;
100+
using const_reference = const absl::Cord&;
101+
using reference = absl::Cord&;
102+
using const_iterator = typename type::const_iterator;
103+
using iterator = typename type::iterator;
104+
};
105+
106+
} // namespace internal
107+
} // namespace protobuf
108+
} // namespace google
109+
110+
#endif // GOOGLE_PROTOBUF_REPEATED_FIELD_PROXY_TRAITS_H__

0 commit comments

Comments
 (0)