Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
P
protobuf
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
protobuf
Commits
ceb561d6
Commit
ceb561d6
authored
Jun 25, 2009
by
kenton@google.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add Swap(), SwapElements(), and RemoveLast() to Reflection. Patch by Scott Stafford.
parent
f22943c7
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
414 additions
and
19 deletions
+414
-19
CHANGES.txt
CHANGES.txt
+10
-0
CONTRIBUTORS.txt
CONTRIBUTORS.txt
+2
-0
cpp_message.cc
src/google/protobuf/compiler/cpp/cpp_message.cc
+20
-15
descriptor.pb.cc
src/google/protobuf/descriptor.pb.cc
+0
-0
extension_set.cc
src/google/protobuf/extension_set.cc
+82
-0
extension_set.h
src/google/protobuf/extension_set.h
+3
-0
generated_message_reflection.cc
src/google/protobuf/generated_message_reflection.cc
+87
-2
generated_message_reflection.h
src/google/protobuf/generated_message_reflection.h
+4
-0
generated_message_reflection_unittest.cc
src/google/protobuf/generated_message_reflection_unittest.cc
+116
-0
message.h
src/google/protobuf/message.h
+20
-1
repeated_field.h
src/google/protobuf/repeated_field.h
+56
-1
test_util.cc
src/google/protobuf/test_util.cc
+0
-0
test_util.h
src/google/protobuf/test_util.h
+14
-0
No files found.
CHANGES.txt
View file @
ceb561d6
????-??-?? version 2.1.1:
C++
* Fixed bug where Message.Swap(Message) was only implemented for
optimize_for_speed. Swap now properly implemented in both modes
(Issue 91).
* Added RemoveLast and SwapElements(index1, index2) to Reflection
interface for repeated elements.
* Added Swap(Message) to Reflection interface.
2009-05-13 version 2.1.0:
General
...
...
CONTRIBUTORS.txt
View file @
ceb561d6
...
...
@@ -70,3 +70,5 @@ Patch contributors:
* Small patch improving performance of in Python serialization.
Alexandre Vassalotti <alexandre@peadrop.com>
* Emacs mode for Protocol Buffers (editors/protobuf-mode.el).
Scott Stafford <scott.stafford@gmail.com>
* Added Swap(), SwapElements(), and RemoveLast() to Reflection interface.
src/google/protobuf/compiler/cpp/cpp_message.cc
View file @
ceb561d6
...
...
@@ -684,13 +684,13 @@ GenerateClassMethods(io::Printer* printer) {
GenerateCopyFrom
(
printer
);
printer
->
Print
(
"
\n
"
);
GenerateSwap
(
printer
);
printer
->
Print
(
"
\n
"
);
GenerateIsInitialized
(
printer
);
printer
->
Print
(
"
\n
"
);
}
GenerateSwap
(
printer
);
printer
->
Print
(
"
\n
"
);
printer
->
Print
(
"const ::google::protobuf::Descriptor* $classname$::GetDescriptor() const {
\n
"
" return descriptor();
\n
"
...
...
@@ -967,22 +967,27 @@ GenerateSwap(io::Printer* printer) {
printer
->
Print
(
"if (other != this) {
\n
"
);
printer
->
Indent
();
for
(
int
i
=
0
;
i
<
descriptor_
->
field_count
();
i
++
)
{
const
FieldDescriptor
*
field
=
descriptor_
->
field
(
i
);
field_generators_
.
get
(
field
).
GenerateSwappingCode
(
printer
);
}
if
(
descriptor_
->
file
()
->
options
().
optimize_for
()
==
FileOptions
::
SPEED
)
{
for
(
int
i
=
0
;
i
<
descriptor_
->
field_count
();
i
++
)
{
const
FieldDescriptor
*
field
=
descriptor_
->
field
(
i
);
field_generators_
.
get
(
field
).
GenerateSwappingCode
(
printer
);
}
for
(
int
i
=
0
;
i
<
(
descriptor_
->
field_count
()
+
31
)
/
32
;
++
i
)
{
printer
->
Print
(
"std::swap(_has_bits_[$i$], other->_has_bits_[$i$]);
\n
"
,
"i"
,
SimpleItoa
(
i
));
}
for
(
int
i
=
0
;
i
<
(
descriptor_
->
field_count
()
+
31
)
/
32
;
++
i
)
{
printer
->
Print
(
"std::swap(_has_bits_[$i$], other->_has_bits_[$i$]);
\n
"
,
"i"
,
SimpleItoa
(
i
));
}
printer
->
Print
(
"_unknown_fields_.Swap(&other->_unknown_fields_);
\n
"
);
printer
->
Print
(
"std::swap(_cached_size_, other->_cached_size_);
\n
"
);
if
(
descriptor_
->
extension_range_count
()
>
0
)
{
printer
->
Print
(
"_extensions_.Swap(&other->_extensions_);
\n
"
);
printer
->
Print
(
"_unknown_fields_.Swap(&other->_unknown_fields_);
\n
"
);
printer
->
Print
(
"std::swap(_cached_size_, other->_cached_size_);
\n
"
);
if
(
descriptor_
->
extension_range_count
()
>
0
)
{
printer
->
Print
(
"_extensions_.Swap(&other->_extensions_);
\n
"
);
}
}
else
{
printer
->
Print
(
"GetReflection()->Swap(this, other);"
);
}
printer
->
Outdent
();
printer
->
Print
(
"}
\n
"
);
printer
->
Outdent
();
...
...
src/google/protobuf/descriptor.pb.cc
View file @
ceb561d6
This diff is collapsed.
Click to expand it.
src/google/protobuf/extension_set.cc
View file @
ceb561d6
...
...
@@ -497,6 +497,88 @@ Message* ExtensionSet::AddMessage(int number, FieldType type,
#undef GOOGLE_DCHECK_TYPE
void
ExtensionSet
::
RemoveLast
(
int
number
)
{
map
<
int
,
Extension
>::
iterator
iter
=
extensions_
.
find
(
number
);
GOOGLE_CHECK
(
iter
!=
extensions_
.
end
())
<<
"Index out-of-bounds (field is empty)."
;
Extension
*
extension
=
&
iter
->
second
;
GOOGLE_DCHECK
(
extension
->
is_repeated
);
switch
(
cpp_type
(
extension
->
type
))
{
case
FieldDescriptor
:
:
CPPTYPE_INT32
:
extension
->
repeated_int32_value
->
RemoveLast
();
break
;
case
FieldDescriptor
:
:
CPPTYPE_INT64
:
extension
->
repeated_int64_value
->
RemoveLast
();
break
;
case
FieldDescriptor
:
:
CPPTYPE_UINT32
:
extension
->
repeated_uint32_value
->
RemoveLast
();
break
;
case
FieldDescriptor
:
:
CPPTYPE_UINT64
:
extension
->
repeated_uint64_value
->
RemoveLast
();
break
;
case
FieldDescriptor
:
:
CPPTYPE_FLOAT
:
extension
->
repeated_float_value
->
RemoveLast
();
break
;
case
FieldDescriptor
:
:
CPPTYPE_DOUBLE
:
extension
->
repeated_double_value
->
RemoveLast
();
break
;
case
FieldDescriptor
:
:
CPPTYPE_BOOL
:
extension
->
repeated_bool_value
->
RemoveLast
();
break
;
case
FieldDescriptor
:
:
CPPTYPE_ENUM
:
extension
->
repeated_enum_value
->
RemoveLast
();
break
;
case
FieldDescriptor
:
:
CPPTYPE_STRING
:
extension
->
repeated_string_value
->
RemoveLast
();
break
;
case
FieldDescriptor
:
:
CPPTYPE_MESSAGE
:
extension
->
repeated_message_value
->
RemoveLast
();
break
;
}
}
void
ExtensionSet
::
SwapElements
(
int
number
,
int
index1
,
int
index2
)
{
map
<
int
,
Extension
>::
iterator
iter
=
extensions_
.
find
(
number
);
GOOGLE_CHECK
(
iter
!=
extensions_
.
end
())
<<
"Index out-of-bounds (field is empty)."
;
Extension
*
extension
=
&
iter
->
second
;
GOOGLE_DCHECK
(
extension
->
is_repeated
);
switch
(
cpp_type
(
extension
->
type
))
{
case
FieldDescriptor
:
:
CPPTYPE_INT32
:
extension
->
repeated_int32_value
->
SwapElements
(
index1
,
index2
);
break
;
case
FieldDescriptor
:
:
CPPTYPE_INT64
:
extension
->
repeated_int64_value
->
SwapElements
(
index1
,
index2
);
break
;
case
FieldDescriptor
:
:
CPPTYPE_UINT32
:
extension
->
repeated_uint32_value
->
SwapElements
(
index1
,
index2
);
break
;
case
FieldDescriptor
:
:
CPPTYPE_UINT64
:
extension
->
repeated_uint64_value
->
SwapElements
(
index1
,
index2
);
break
;
case
FieldDescriptor
:
:
CPPTYPE_FLOAT
:
extension
->
repeated_float_value
->
SwapElements
(
index1
,
index2
);
break
;
case
FieldDescriptor
:
:
CPPTYPE_DOUBLE
:
extension
->
repeated_double_value
->
SwapElements
(
index1
,
index2
);
break
;
case
FieldDescriptor
:
:
CPPTYPE_BOOL
:
extension
->
repeated_bool_value
->
SwapElements
(
index1
,
index2
);
break
;
case
FieldDescriptor
:
:
CPPTYPE_ENUM
:
extension
->
repeated_enum_value
->
SwapElements
(
index1
,
index2
);
break
;
case
FieldDescriptor
:
:
CPPTYPE_STRING
:
extension
->
repeated_string_value
->
SwapElements
(
index1
,
index2
);
break
;
case
FieldDescriptor
:
:
CPPTYPE_MESSAGE
:
extension
->
repeated_message_value
->
SwapElements
(
index1
,
index2
);
break
;
}
}
// ===================================================================
void
ExtensionSet
::
Clear
()
{
...
...
src/google/protobuf/extension_set.h
View file @
ceb561d6
...
...
@@ -228,6 +228,9 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
const
Descriptor
*
message_type
,
MessageFactory
*
factory
);
void
RemoveLast
(
int
number
);
void
SwapElements
(
int
number
,
int
index1
,
int
index2
);
// -----------------------------------------------------------------
// TODO(kenton): Hardcore memory management accessors
...
...
src/google/protobuf/generated_message_reflection.cc
View file @
ceb561d6
...
...
@@ -269,6 +269,61 @@ int GeneratedMessageReflection::SpaceUsed(const Message& message) const {
return
total_size
;
}
void
GeneratedMessageReflection
::
Swap
(
Message
*
message1
,
Message
*
message2
)
const
{
if
(
message1
==
message2
)
return
;
GOOGLE_CHECK_EQ
(
message1
->
GetReflection
(),
this
)
<<
"Tried to swap using reflection object incompatible with message1."
;
GOOGLE_CHECK_EQ
(
message2
->
GetReflection
(),
this
)
<<
"Tried to swap using reflection object incompatible with message2."
;
uint32
*
has_bits1
=
MutableHasBits
(
message1
);
uint32
*
has_bits2
=
MutableHasBits
(
message2
);
int
has_bits_size
=
(
descriptor_
->
field_count
()
+
31
)
/
32
;
for
(
int
i
=
0
;
i
<
has_bits_size
;
i
++
)
{
std
::
swap
(
has_bits1
[
i
],
has_bits2
[
i
]);
}
for
(
int
i
=
0
;
i
<
descriptor_
->
field_count
();
i
++
)
{
const
FieldDescriptor
*
field
=
descriptor_
->
field
(
i
);
if
(
field
->
is_repeated
())
{
MutableRaw
<
GenericRepeatedField
>
(
message1
,
field
)
->
GenericSwap
(
MutableRaw
<
GenericRepeatedField
>
(
message2
,
field
));
}
else
{
switch
(
field
->
cpp_type
())
{
#define SWAP_VALUES(CPPTYPE, TYPE) \
case FieldDescriptor::CPPTYPE_##CPPTYPE: \
swap(*MutableRaw<TYPE>(message1, field), \
*MutableRaw<TYPE>(message2, field)); \
break;
SWAP_VALUES
(
INT32
,
int32
);
SWAP_VALUES
(
INT64
,
int64
);
SWAP_VALUES
(
UINT32
,
uint32
);
SWAP_VALUES
(
UINT64
,
uint64
);
SWAP_VALUES
(
FLOAT
,
float
);
SWAP_VALUES
(
DOUBLE
,
double
);
SWAP_VALUES
(
BOOL
,
bool
);
SWAP_VALUES
(
ENUM
,
int32
);
SWAP_VALUES
(
STRING
,
string
*
);
SWAP_VALUES
(
MESSAGE
,
Message
*
);
#undef SWAP_PRIMITIVE_VALUES
default
:
GOOGLE_LOG
(
FATAL
)
<<
"Unimplemented type: "
<<
field
->
cpp_type
();
}
}
}
if
(
extensions_offset_
!=
-
1
)
{
MutableExtensionSet
(
message1
)
->
Swap
(
MutableExtensionSet
(
message2
));
}
MutableUnknownFields
(
message1
)
->
Swap
(
MutableUnknownFields
(
message2
));
}
// -------------------------------------------------------------------
bool
GeneratedMessageReflection
::
HasField
(
const
Message
&
message
,
...
...
@@ -285,8 +340,8 @@ bool GeneratedMessageReflection::HasField(const Message& message,
int
GeneratedMessageReflection
::
FieldSize
(
const
Message
&
message
,
const
FieldDescriptor
*
field
)
const
{
USAGE_CHECK_MESSAGE_TYPE
(
HasField
);
USAGE_CHECK_REPEATED
(
HasField
);
USAGE_CHECK_MESSAGE_TYPE
(
FieldSize
);
USAGE_CHECK_REPEATED
(
FieldSize
);
if
(
field
->
is_extension
())
{
return
GetExtensionSet
(
message
).
ExtensionSize
(
field
->
number
());
...
...
@@ -350,6 +405,36 @@ void GeneratedMessageReflection::ClearField(
}
}
void
GeneratedMessageReflection
::
RemoveLast
(
Message
*
message
,
const
FieldDescriptor
*
field
)
const
{
USAGE_CHECK_MESSAGE_TYPE
(
RemoveLast
);
USAGE_CHECK_REPEATED
(
RemoveLast
);
if
(
field
->
is_extension
())
{
MutableExtensionSet
(
message
)
->
RemoveLast
(
field
->
number
());
}
else
{
MutableRaw
<
GenericRepeatedField
>
(
message
,
field
)
->
GenericRemoveLast
();
}
}
void
GeneratedMessageReflection
::
SwapElements
(
Message
*
message
,
const
FieldDescriptor
*
field
,
int
index1
,
int
index2
)
const
{
USAGE_CHECK_MESSAGE_TYPE
(
Swap
);
USAGE_CHECK_REPEATED
(
Swap
);
if
(
field
->
is_extension
())
{
MutableExtensionSet
(
message
)
->
SwapElements
(
field
->
number
(),
index1
,
index2
);
}
else
{
MutableRaw
<
GenericRepeatedField
>
(
message
,
field
)
->
GenericSwapElements
(
index1
,
index2
);
}
}
namespace
{
// Comparison functor for sorting FieldDescriptors by field number.
struct
FieldNumberSorter
{
...
...
src/google/protobuf/generated_message_reflection.h
View file @
ceb561d6
...
...
@@ -140,6 +140,10 @@ class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection {
bool
HasField
(
const
Message
&
message
,
const
FieldDescriptor
*
field
)
const
;
int
FieldSize
(
const
Message
&
message
,
const
FieldDescriptor
*
field
)
const
;
void
ClearField
(
Message
*
message
,
const
FieldDescriptor
*
field
)
const
;
void
RemoveLast
(
Message
*
message
,
const
FieldDescriptor
*
field
)
const
;
void
Swap
(
Message
*
message1
,
Message
*
message2
)
const
;
void
SwapElements
(
Message
*
message
,
const
FieldDescriptor
*
field
,
int
index1
,
int
index2
)
const
;
void
ListFields
(
const
Message
&
message
,
vector
<
const
FieldDescriptor
*>*
output
)
const
;
...
...
src/google/protobuf/generated_message_reflection_unittest.cc
View file @
ceb561d6
...
...
@@ -146,6 +146,122 @@ TEST(GeneratedMessageReflectionTest, DefaultsAfterClear) {
&
reflection
->
GetMessage
(
message
,
F
(
"optional_import_message"
)));
}
TEST
(
GeneratedMessageReflectionTest
,
Swap
)
{
unittest
::
TestAllTypes
message1
;
unittest
::
TestAllTypes
message2
;
TestUtil
::
SetAllFields
(
&
message1
);
const
Reflection
*
reflection
=
message1
.
GetReflection
();
reflection
->
Swap
(
&
message1
,
&
message2
);
TestUtil
::
ExpectClear
(
message1
);
TestUtil
::
ExpectAllFieldsSet
(
message2
);
}
TEST
(
GeneratedMessageReflectionTest
,
SwapWithBothSet
)
{
unittest
::
TestAllTypes
message1
;
unittest
::
TestAllTypes
message2
;
TestUtil
::
SetAllFields
(
&
message1
);
TestUtil
::
SetAllFields
(
&
message2
);
TestUtil
::
ModifyRepeatedFields
(
&
message2
);
const
Reflection
*
reflection
=
message1
.
GetReflection
();
reflection
->
Swap
(
&
message1
,
&
message2
);
TestUtil
::
ExpectRepeatedFieldsModified
(
message1
);
TestUtil
::
ExpectAllFieldsSet
(
message2
);
message1
.
set_optional_int32
(
532819
);
reflection
->
Swap
(
&
message1
,
&
message2
);
EXPECT_EQ
(
532819
,
message2
.
optional_int32
());
}
TEST
(
GeneratedMessageReflectionTest
,
SwapExtensions
)
{
unittest
::
TestAllExtensions
message1
;
unittest
::
TestAllExtensions
message2
;
TestUtil
::
SetAllExtensions
(
&
message1
);
const
Reflection
*
reflection
=
message1
.
GetReflection
();
reflection
->
Swap
(
&
message1
,
&
message2
);
TestUtil
::
ExpectExtensionsClear
(
message1
);
TestUtil
::
ExpectAllExtensionsSet
(
message2
);
}
TEST
(
GeneratedMessageReflectionTest
,
SwapUnknown
)
{
unittest
::
TestEmptyMessage
message1
,
message2
;
message1
.
mutable_unknown_fields
()
->
AddVarint
(
1234
,
1
);
EXPECT_EQ
(
1
,
message1
.
unknown_fields
().
field_count
());
EXPECT_EQ
(
0
,
message2
.
unknown_fields
().
field_count
());
const
Reflection
*
reflection
=
message1
.
GetReflection
();
reflection
->
Swap
(
&
message1
,
&
message2
);
EXPECT_EQ
(
0
,
message1
.
unknown_fields
().
field_count
());
EXPECT_EQ
(
1
,
message2
.
unknown_fields
().
field_count
());
}
TEST
(
GeneratedMessageReflectionTest
,
RemoveLast
)
{
unittest
::
TestAllTypes
message
;
TestUtil
::
ReflectionTester
reflection_tester
(
unittest
::
TestAllTypes
::
descriptor
());
TestUtil
::
SetAllFields
(
&
message
);
reflection_tester
.
RemoveLastRepeatedsViaReflection
(
&
message
);
TestUtil
::
ExpectLastRepeatedsRemoved
(
message
);
}
TEST
(
GeneratedMessageReflectionTest
,
RemoveLastExtensions
)
{
unittest
::
TestAllExtensions
message
;
TestUtil
::
ReflectionTester
reflection_tester
(
unittest
::
TestAllExtensions
::
descriptor
());
TestUtil
::
SetAllExtensions
(
&
message
);
reflection_tester
.
RemoveLastRepeatedsViaReflection
(
&
message
);
TestUtil
::
ExpectLastRepeatedExtensionsRemoved
(
message
);
}
TEST
(
GeneratedMessageReflectionTest
,
SwapRepeatedElements
)
{
unittest
::
TestAllTypes
message
;
TestUtil
::
ReflectionTester
reflection_tester
(
unittest
::
TestAllTypes
::
descriptor
());
TestUtil
::
SetAllFields
(
&
message
);
// Swap and test that fields are all swapped.
reflection_tester
.
SwapRepeatedsViaReflection
(
&
message
);
TestUtil
::
ExpectRepeatedsSwapped
(
message
);
// Swap back and test that fields are all back to original values.
reflection_tester
.
SwapRepeatedsViaReflection
(
&
message
);
TestUtil
::
ExpectAllFieldsSet
(
message
);
}
TEST
(
GeneratedMessageReflectionTest
,
SwapRepeatedElementsExtension
)
{
unittest
::
TestAllExtensions
message
;
TestUtil
::
ReflectionTester
reflection_tester
(
unittest
::
TestAllExtensions
::
descriptor
());
TestUtil
::
SetAllExtensions
(
&
message
);
// Swap and test that fields are all swapped.
reflection_tester
.
SwapRepeatedsViaReflection
(
&
message
);
TestUtil
::
ExpectRepeatedExtensionsSwapped
(
message
);
// Swap back and test that fields are all back to original values.
reflection_tester
.
SwapRepeatedsViaReflection
(
&
message
);
TestUtil
::
ExpectAllExtensionsSet
(
message
);
}
TEST
(
GeneratedMessageReflectionTest
,
Extensions
)
{
// Set every extension to a unique value then go back and check all those
// values.
...
...
src/google/protobuf/message.h
View file @
ceb561d6
...
...
@@ -97,7 +97,7 @@
// // Use the reflection interface to examine the contents.
// const Reflection* reflection = foo->GetReflection();
// assert(reflection->GetString(foo, text_field) == "Hello World!");
// assert(reflection->
CountField
(foo, numbers_field) == 3);
// assert(reflection->
FieldSize
(foo, numbers_field) == 3);
// assert(reflection->GetInt32(foo, numbers_field, 0) == 1);
// assert(reflection->GetInt32(foo, numbers_field, 1) == 5);
// assert(reflection->GetInt32(foo, numbers_field, 2) == 42);
...
...
@@ -494,6 +494,25 @@ class LIBPROTOBUF_EXPORT Reflection {
virtual
void
ClearField
(
Message
*
message
,
const
FieldDescriptor
*
field
)
const
=
0
;
// Remove the last element of a repeated field.
// We don't provide a way to remove any element other than the last
// because it invites inefficient use, such as O(n^2) filtering loops
// that should have been O(n). If you want to remove an element other
// than the last, the best way to do it is to re-arrange the elements
// (using Swap()) so that the one you want removed is at the end, then
// call RemoveLast().
virtual
void
RemoveLast
(
Message
*
message
,
const
FieldDescriptor
*
field
)
const
=
0
;
// Swap the complete contents of two messages.
virtual
void
Swap
(
Message
*
message1
,
Message
*
message2
)
const
=
0
;
// Swap two elements of a repeated field.
virtual
void
SwapElements
(
Message
*
message
,
const
FieldDescriptor
*
field
,
int
index1
,
int
index2
)
const
=
0
;
// List all fields of the message which are currently set. This includes
// extensions. Singular fields will only be listed if HasField(field) would
// return true and repeated fields will only be listed if FieldSize(field)
...
...
src/google/protobuf/repeated_field.h
View file @
ceb561d6
...
...
@@ -86,6 +86,9 @@ class LIBPROTOBUF_EXPORT GenericRepeatedField {
virtual
void
*
GenericMutable
(
int
index
)
=
0
;
virtual
void
*
GenericAdd
()
=
0
;
virtual
void
GenericClear
()
=
0
;
virtual
void
GenericRemoveLast
()
=
0
;
virtual
void
GenericSwap
(
GenericRepeatedField
*
other
)
=
0
;
virtual
void
GenericSwapElements
(
int
index1
,
int
index2
)
=
0
;
virtual
int
GenericSize
()
const
=
0
;
virtual
int
GenericSpaceUsedExcludingSelf
()
const
=
0
;
...
...
@@ -135,6 +138,9 @@ class RepeatedField : public internal::GenericRepeatedField {
// Swap entire contents with "other".
void
Swap
(
RepeatedField
*
other
);
// Swap two elements of a repeated field.
void
SwapElements
(
int
index1
,
int
index2
);
// STL-like iterator support
typedef
Element
*
iterator
;
typedef
const
Element
*
const_iterator
;
...
...
@@ -154,6 +160,9 @@ class RepeatedField : public internal::GenericRepeatedField {
void
*
GenericMutable
(
int
index
);
void
*
GenericAdd
();
void
GenericClear
();
void
GenericRemoveLast
();
void
GenericSwap
(
GenericRepeatedField
*
other
);
void
GenericSwapElements
(
int
index1
,
int
index2
);
int
GenericSize
()
const
;
int
GenericSpaceUsedExcludingSelf
()
const
;
...
...
@@ -214,6 +223,9 @@ class RepeatedPtrField : public internal::GenericRepeatedField {
// Swap entire contents with "other".
void
Swap
(
RepeatedPtrField
*
other
);
// Swap two elements of a repeated field.
void
SwapElements
(
int
index1
,
int
index2
);
// STL-like iterator support
typedef
internal
::
RepeatedPtrIterator
<
Element
**>
iterator
;
typedef
internal
::
RepeatedPtrIterator
<
const
Element
*
const
*>
const_iterator
;
...
...
@@ -266,6 +278,9 @@ class RepeatedPtrField : public internal::GenericRepeatedField {
void
*
GenericMutable
(
int
index
);
void
*
GenericAdd
();
void
GenericClear
();
void
GenericRemoveLast
();
void
GenericSwap
(
GenericRepeatedField
*
other
);
void
GenericSwapElements
(
int
index1
,
int
index2
);
int
GenericSize
()
const
;
int
GenericSpaceUsedExcludingSelf
()
const
;
...
...
@@ -395,6 +410,11 @@ void RepeatedField<Element>::Swap(RepeatedField* other) {
}
}
template
<
typename
Element
>
void
RepeatedField
<
Element
>::
SwapElements
(
int
index1
,
int
index2
)
{
swap
(
*
Mutable
(
index1
),
*
Mutable
(
index2
));
}
template
<
typename
Element
>
inline
typename
RepeatedField
<
Element
>::
iterator
RepeatedField
<
Element
>::
begin
()
{
...
...
@@ -443,6 +463,21 @@ void RepeatedField<Element>::GenericClear() {
Clear
();
}
template
<
typename
Element
>
void
RepeatedField
<
Element
>::
GenericRemoveLast
()
{
RemoveLast
();
}
template
<
typename
Element
>
void
RepeatedField
<
Element
>::
GenericSwap
(
GenericRepeatedField
*
other
)
{
Swap
(
down_cast
<
RepeatedField
<
Element
>*>
(
other
));
}
template
<
typename
Element
>
void
RepeatedField
<
Element
>::
GenericSwapElements
(
int
index1
,
int
index2
)
{
SwapElements
(
index1
,
index2
);
}
template
<
typename
Element
>
int
RepeatedField
<
Element
>::
GenericSize
()
const
{
return
size
();
...
...
@@ -622,6 +657,11 @@ void RepeatedPtrField<Element>::Swap(RepeatedPtrField* other) {
}
}
template
<
typename
Element
>
void
RepeatedPtrField
<
Element
>::
SwapElements
(
int
index1
,
int
index2
)
{
swap
(
elements_
[
index1
],
elements_
[
index2
]);
}
template
<
typename
Element
>
inline
int
RepeatedPtrField
<
Element
>::
SpaceUsedExcludingSelf
()
const
{
int
allocated_bytes
=
...
...
@@ -707,6 +747,21 @@ void RepeatedPtrField<Element>::GenericClear() {
Clear
();
}
template
<
typename
Element
>
void
RepeatedPtrField
<
Element
>::
GenericRemoveLast
()
{
RemoveLast
();
}
template
<
typename
Element
>
void
RepeatedPtrField
<
Element
>::
GenericSwap
(
GenericRepeatedField
*
other
)
{
Swap
(
down_cast
<
RepeatedPtrField
<
Element
>*>
(
other
));
}
template
<
typename
Element
>
void
RepeatedPtrField
<
Element
>::
GenericSwapElements
(
int
index1
,
int
index2
)
{
SwapElements
(
index1
,
index2
);
}
template
<
typename
Element
>
int
RepeatedPtrField
<
Element
>::
GenericSize
()
const
{
return
size
();
...
...
@@ -736,7 +791,7 @@ inline Element* RepeatedPtrField<Element>::NewElement() {
return
new
Element
;
}
// RepeatedPtrField<Message> is alowed but requires a prototype since Message
// RepeatedPtrField<Message> is al
l
owed but requires a prototype since Message
// is abstract.
template
<>
inline
Message
*
RepeatedPtrField
<
Message
>::
NewElement
()
{
...
...
src/google/protobuf/test_util.cc
View file @
ceb561d6
This diff is collapsed.
Click to expand it.
src/google/protobuf/test_util.h
View file @
ceb561d6
...
...
@@ -96,6 +96,17 @@ class TestUtil {
// SetAllFieldsAndExtensions().
static
void
ExpectAllFieldsAndExtensionsInOrder
(
const
string
&
serialized
);
// Check that all repeated fields have had their last elements removed.
static
void
ExpectLastRepeatedsRemoved
(
const
unittest
::
TestAllTypes
&
message
);
static
void
ExpectLastRepeatedExtensionsRemoved
(
const
unittest
::
TestAllExtensions
&
message
);
// Check that all repeated fields have had their first and last elements swapped.
static
void
ExpectRepeatedsSwapped
(
const
unittest
::
TestAllTypes
&
message
);
static
void
ExpectRepeatedExtensionsSwapped
(
const
unittest
::
TestAllExtensions
&
message
);
// Like above, but use the reflection interface.
class
ReflectionTester
{
public
:
...
...
@@ -116,6 +127,9 @@ class TestUtil {
void
ExpectPackedFieldsSetViaReflection
(
const
Message
&
message
);
void
ExpectPackedClearViaReflection
(
const
Message
&
message
);
void
RemoveLastRepeatedsViaReflection
(
Message
*
message
);
void
SwapRepeatedsViaReflection
(
Message
*
message
);
private
:
const
FieldDescriptor
*
F
(
const
string
&
name
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment