protobuf 2.2.5-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (256) hide show
  1. data/.gitignore +17 -0
  2. data/.travis.yml +9 -0
  3. data/.yardopts +5 -0
  4. data/Gemfile +3 -0
  5. data/README.md +316 -0
  6. data/Rakefile +29 -0
  7. data/UPGRADING.md +60 -0
  8. data/bin/rpc_server +5 -0
  9. data/bin/rprotoc +62 -0
  10. data/examples/addressbook.pb.rb +55 -0
  11. data/examples/addressbook.proto +24 -0
  12. data/examples/reading_a_message.rb +32 -0
  13. data/examples/writing_a_message.rb +46 -0
  14. data/ext/protobuf-2.4.1/src/google/protobuf/compiler/code_generator.h +142 -0
  15. data/ext/protobuf-2.4.1/src/google/protobuf/compiler/command_line_interface.h +318 -0
  16. data/ext/protobuf-2.4.1/src/google/protobuf/compiler/cpp/cpp_enum.h +99 -0
  17. data/ext/protobuf-2.4.1/src/google/protobuf/compiler/cpp/cpp_enum_field.h +103 -0
  18. data/ext/protobuf-2.4.1/src/google/protobuf/compiler/cpp/cpp_extension.h +85 -0
  19. data/ext/protobuf-2.4.1/src/google/protobuf/compiler/cpp/cpp_field.h +167 -0
  20. data/ext/protobuf-2.4.1/src/google/protobuf/compiler/cpp/cpp_file.h +98 -0
  21. data/ext/protobuf-2.4.1/src/google/protobuf/compiler/cpp/cpp_generator.h +72 -0
  22. data/ext/protobuf-2.4.1/src/google/protobuf/compiler/cpp/cpp_helpers.h +159 -0
  23. data/ext/protobuf-2.4.1/src/google/protobuf/compiler/cpp/cpp_message.h +170 -0
  24. data/ext/protobuf-2.4.1/src/google/protobuf/compiler/cpp/cpp_message_field.h +102 -0
  25. data/ext/protobuf-2.4.1/src/google/protobuf/compiler/cpp/cpp_primitive_field.h +103 -0
  26. data/ext/protobuf-2.4.1/src/google/protobuf/compiler/cpp/cpp_service.h +118 -0
  27. data/ext/protobuf-2.4.1/src/google/protobuf/compiler/cpp/cpp_string_field.h +104 -0
  28. data/ext/protobuf-2.4.1/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.h +2721 -0
  29. data/ext/protobuf-2.4.1/src/google/protobuf/compiler/importer.h +303 -0
  30. data/ext/protobuf-2.4.1/src/google/protobuf/compiler/java/java_enum.h +84 -0
  31. data/ext/protobuf-2.4.1/src/google/protobuf/compiler/java/java_enum_field.h +121 -0
  32. data/ext/protobuf-2.4.1/src/google/protobuf/compiler/java/java_extension.h +77 -0
  33. data/ext/protobuf-2.4.1/src/google/protobuf/compiler/java/java_field.h +108 -0
  34. data/ext/protobuf-2.4.1/src/google/protobuf/compiler/java/java_file.h +101 -0
  35. data/ext/protobuf-2.4.1/src/google/protobuf/compiler/java/java_generator.h +72 -0
  36. data/ext/protobuf-2.4.1/src/google/protobuf/compiler/java/java_helpers.h +213 -0
  37. data/ext/protobuf-2.4.1/src/google/protobuf/compiler/java/java_message.h +109 -0
  38. data/ext/protobuf-2.4.1/src/google/protobuf/compiler/java/java_message_field.h +134 -0
  39. data/ext/protobuf-2.4.1/src/google/protobuf/compiler/java/java_primitive_field.h +121 -0
  40. data/ext/protobuf-2.4.1/src/google/protobuf/compiler/java/java_service.h +113 -0
  41. data/ext/protobuf-2.4.1/src/google/protobuf/compiler/java/java_string_field.h +120 -0
  42. data/ext/protobuf-2.4.1/src/google/protobuf/compiler/mock_code_generator.h +113 -0
  43. data/ext/protobuf-2.4.1/src/google/protobuf/compiler/package_info.h +64 -0
  44. data/ext/protobuf-2.4.1/src/google/protobuf/compiler/parser.h +434 -0
  45. data/ext/protobuf-2.4.1/src/google/protobuf/compiler/plugin.h +73 -0
  46. data/ext/protobuf-2.4.1/src/google/protobuf/compiler/plugin.pb.h +790 -0
  47. data/ext/protobuf-2.4.1/src/google/protobuf/compiler/python/python_generator.h +156 -0
  48. data/ext/protobuf-2.4.1/src/google/protobuf/compiler/subprocess.h +108 -0
  49. data/ext/protobuf-2.4.1/src/google/protobuf/compiler/zip_writer.h +93 -0
  50. data/ext/protobuf-2.4.1/src/google/protobuf/descriptor.h +1367 -0
  51. data/ext/protobuf-2.4.1/src/google/protobuf/descriptor.pb.h +5223 -0
  52. data/ext/protobuf-2.4.1/src/google/protobuf/descriptor_database.h +366 -0
  53. data/ext/protobuf-2.4.1/src/google/protobuf/dynamic_message.h +136 -0
  54. data/ext/protobuf-2.4.1/src/google/protobuf/extension_set.h +904 -0
  55. data/ext/protobuf-2.4.1/src/google/protobuf/generated_message_reflection.h +424 -0
  56. data/ext/protobuf-2.4.1/src/google/protobuf/generated_message_util.h +82 -0
  57. data/ext/protobuf-2.4.1/src/google/protobuf/io/coded_stream.h +1102 -0
  58. data/ext/protobuf-2.4.1/src/google/protobuf/io/coded_stream_inl.h +64 -0
  59. data/ext/protobuf-2.4.1/src/google/protobuf/io/gzip_stream.h +207 -0
  60. data/ext/protobuf-2.4.1/src/google/protobuf/io/package_info.h +54 -0
  61. data/ext/protobuf-2.4.1/src/google/protobuf/io/printer.h +136 -0
  62. data/ext/protobuf-2.4.1/src/google/protobuf/io/tokenizer.h +313 -0
  63. data/ext/protobuf-2.4.1/src/google/protobuf/io/zero_copy_stream.h +238 -0
  64. data/ext/protobuf-2.4.1/src/google/protobuf/io/zero_copy_stream_impl.h +357 -0
  65. data/ext/protobuf-2.4.1/src/google/protobuf/io/zero_copy_stream_impl_lite.h +340 -0
  66. data/ext/protobuf-2.4.1/src/google/protobuf/message.h +692 -0
  67. data/ext/protobuf-2.4.1/src/google/protobuf/message_lite.h +239 -0
  68. data/ext/protobuf-2.4.1/src/google/protobuf/package_info.h +64 -0
  69. data/ext/protobuf-2.4.1/src/google/protobuf/reflection_ops.h +80 -0
  70. data/ext/protobuf-2.4.1/src/google/protobuf/repeated_field.h +1295 -0
  71. data/ext/protobuf-2.4.1/src/google/protobuf/service.h +291 -0
  72. data/ext/protobuf-2.4.1/src/google/protobuf/stubs/common.h +1211 -0
  73. data/ext/protobuf-2.4.1/src/google/protobuf/stubs/hash.h +220 -0
  74. data/ext/protobuf-2.4.1/src/google/protobuf/stubs/map-util.h +119 -0
  75. data/ext/protobuf-2.4.1/src/google/protobuf/stubs/once.h +123 -0
  76. data/ext/protobuf-2.4.1/src/google/protobuf/stubs/stl_util-inl.h +121 -0
  77. data/ext/protobuf-2.4.1/src/google/protobuf/stubs/strutil.h +457 -0
  78. data/ext/protobuf-2.4.1/src/google/protobuf/stubs/substitute.h +170 -0
  79. data/ext/protobuf-2.4.1/src/google/protobuf/test_util.h +174 -0
  80. data/ext/protobuf-2.4.1/src/google/protobuf/test_util_lite.h +101 -0
  81. data/ext/protobuf-2.4.1/src/google/protobuf/testing/file.h +83 -0
  82. data/ext/protobuf-2.4.1/src/google/protobuf/testing/googletest.h +98 -0
  83. data/ext/protobuf-2.4.1/src/google/protobuf/text_format.h +285 -0
  84. data/ext/protobuf-2.4.1/src/google/protobuf/unittest.pb.h +11915 -0
  85. data/ext/protobuf-2.4.1/src/google/protobuf/unittest_custom_options.pb.h +2895 -0
  86. data/ext/protobuf-2.4.1/src/google/protobuf/unittest_embed_optimize_for.pb.h +211 -0
  87. data/ext/protobuf-2.4.1/src/google/protobuf/unittest_empty.pb.h +56 -0
  88. data/ext/protobuf-2.4.1/src/google/protobuf/unittest_import.pb.h +188 -0
  89. data/ext/protobuf-2.4.1/src/google/protobuf/unittest_import_lite.pb.h +151 -0
  90. data/ext/protobuf-2.4.1/src/google/protobuf/unittest_lite.pb.h +4752 -0
  91. data/ext/protobuf-2.4.1/src/google/protobuf/unittest_lite_imports_nonlite.pb.h +150 -0
  92. data/ext/protobuf-2.4.1/src/google/protobuf/unittest_mset.pb.h +816 -0
  93. data/ext/protobuf-2.4.1/src/google/protobuf/unittest_no_generic_services.pb.h +197 -0
  94. data/ext/protobuf-2.4.1/src/google/protobuf/unittest_optimize_for.pb.h +403 -0
  95. data/ext/protobuf-2.4.1/src/google/protobuf/unknown_field_set.h +268 -0
  96. data/ext/protobuf-2.4.1/src/google/protobuf/wire_format.h +304 -0
  97. data/ext/protobuf-2.4.1/src/google/protobuf/wire_format_lite.h +620 -0
  98. data/ext/protobuf-2.4.1/src/google/protobuf/wire_format_lite_inl.h +774 -0
  99. data/ext/ruby_generator/Makefile +10 -0
  100. data/ext/ruby_generator/RubyGenerator.cpp +450 -0
  101. data/ext/ruby_generator/RubyGenerator.h +199 -0
  102. data/ext/ruby_generator/extconf.rb +36 -0
  103. data/ext/ruby_generator/protoc-ruby +0 -0
  104. data/lib/protobuf/cli.rb +188 -0
  105. data/lib/protobuf/enum.rb +58 -0
  106. data/lib/protobuf/enum_value.rb +59 -0
  107. data/lib/protobuf/evented.rb +22 -0
  108. data/lib/protobuf/exceptions.rb +11 -0
  109. data/lib/protobuf/ext/eventmachine.rb +14 -0
  110. data/lib/protobuf/field/base_field.rb +240 -0
  111. data/lib/protobuf/field/bool_field.rb +36 -0
  112. data/lib/protobuf/field/bytes_field.rb +38 -0
  113. data/lib/protobuf/field/double_field.rb +19 -0
  114. data/lib/protobuf/field/enum_field.rb +50 -0
  115. data/lib/protobuf/field/extension_fields.rb +32 -0
  116. data/lib/protobuf/field/field_array.rb +65 -0
  117. data/lib/protobuf/field/fixed32_field.rb +19 -0
  118. data/lib/protobuf/field/fixed64_field.rb +22 -0
  119. data/lib/protobuf/field/float_field.rb +31 -0
  120. data/lib/protobuf/field/int32_field.rb +12 -0
  121. data/lib/protobuf/field/int64_field.rb +12 -0
  122. data/lib/protobuf/field/integer_field.rb +19 -0
  123. data/lib/protobuf/field/message_field.rb +53 -0
  124. data/lib/protobuf/field/sfixed32_field.rb +21 -0
  125. data/lib/protobuf/field/sfixed64_field.rb +24 -0
  126. data/lib/protobuf/field/signed_integer_field.rb +23 -0
  127. data/lib/protobuf/field/sint32_field.rb +12 -0
  128. data/lib/protobuf/field/sint64_field.rb +12 -0
  129. data/lib/protobuf/field/string_field.rb +14 -0
  130. data/lib/protobuf/field/uint32_field.rb +12 -0
  131. data/lib/protobuf/field/uint64_field.rb +12 -0
  132. data/lib/protobuf/field/varint_field.rb +61 -0
  133. data/lib/protobuf/field.rb +57 -0
  134. data/lib/protobuf/logger.rb +86 -0
  135. data/lib/protobuf/message/decoder.rb +83 -0
  136. data/lib/protobuf/message/encoder.rb +48 -0
  137. data/lib/protobuf/message/extend.rb +8 -0
  138. data/lib/protobuf/message/message.rb +1 -0
  139. data/lib/protobuf/message.rb +320 -0
  140. data/lib/protobuf/rpc/buffer.rb +79 -0
  141. data/lib/protobuf/rpc/client.rb +166 -0
  142. data/lib/protobuf/rpc/connector.rb +19 -0
  143. data/lib/protobuf/rpc/connectors/base.rb +38 -0
  144. data/lib/protobuf/rpc/connectors/common.rb +156 -0
  145. data/lib/protobuf/rpc/connectors/em_client.rb +84 -0
  146. data/lib/protobuf/rpc/connectors/eventmachine.rb +87 -0
  147. data/lib/protobuf/rpc/connectors/socket.rb +73 -0
  148. data/lib/protobuf/rpc/connectors/zmq.rb +69 -0
  149. data/lib/protobuf/rpc/error/client_error.rb +31 -0
  150. data/lib/protobuf/rpc/error/server_error.rb +43 -0
  151. data/lib/protobuf/rpc/error.rb +25 -0
  152. data/lib/protobuf/rpc/rpc.pb.rb +118 -0
  153. data/lib/protobuf/rpc/server.rb +89 -0
  154. data/lib/protobuf/rpc/servers/evented/server.rb +41 -0
  155. data/lib/protobuf/rpc/servers/evented_runner.rb +21 -0
  156. data/lib/protobuf/rpc/servers/socket/server.rb +111 -0
  157. data/lib/protobuf/rpc/servers/socket/worker.rb +66 -0
  158. data/lib/protobuf/rpc/servers/socket_runner.rb +27 -0
  159. data/lib/protobuf/rpc/servers/zmq/broker.rb +87 -0
  160. data/lib/protobuf/rpc/servers/zmq/server.rb +50 -0
  161. data/lib/protobuf/rpc/servers/zmq/util.rb +27 -0
  162. data/lib/protobuf/rpc/servers/zmq/worker.rb +60 -0
  163. data/lib/protobuf/rpc/servers/zmq_runner.rb +25 -0
  164. data/lib/protobuf/rpc/service.rb +173 -0
  165. data/lib/protobuf/rpc/service_dispatcher.rb +130 -0
  166. data/lib/protobuf/rpc/service_filters.rb +267 -0
  167. data/lib/protobuf/rpc/stat.rb +83 -0
  168. data/lib/protobuf/socket.rb +22 -0
  169. data/lib/protobuf/version.rb +4 -0
  170. data/lib/protobuf/wire_type.rb +10 -0
  171. data/lib/protobuf/zmq.rb +21 -0
  172. data/lib/protobuf.rb +86 -0
  173. data/proto/rpc.pb.rb +48 -0
  174. data/proto/rpc.proto +73 -0
  175. data/protobuf.gemspec +44 -0
  176. data/spec/benchmark/tasks.rb +179 -0
  177. data/spec/functional/embedded_service_spec.rb +7 -0
  178. data/spec/functional/evented_server_spec.rb +64 -0
  179. data/spec/functional/socket_server_spec.rb +58 -0
  180. data/spec/functional/zmq_server_spec.rb +58 -0
  181. data/spec/lib/protobuf/cli_spec.rb +212 -0
  182. data/spec/lib/protobuf/enum_spec.rb +98 -0
  183. data/spec/lib/protobuf/enum_value_spec.rb +15 -0
  184. data/spec/lib/protobuf/logger_spec.rb +131 -0
  185. data/spec/lib/protobuf/message/encoder_spec.rb +19 -0
  186. data/spec/lib/protobuf/message_spec.rb +209 -0
  187. data/spec/lib/protobuf/rpc/client_spec.rb +158 -0
  188. data/spec/lib/protobuf/rpc/connector_spec.rb +32 -0
  189. data/spec/lib/protobuf/rpc/connectors/base_spec.rb +50 -0
  190. data/spec/lib/protobuf/rpc/connectors/common_spec.rb +128 -0
  191. data/spec/lib/protobuf/rpc/connectors/socket_spec.rb +36 -0
  192. data/spec/lib/protobuf/rpc/connectors/zmq_spec.rb +22 -0
  193. data/spec/lib/protobuf/rpc/servers/evented_server_spec.rb +18 -0
  194. data/spec/lib/protobuf/rpc/servers/socket_server_spec.rb +43 -0
  195. data/spec/lib/protobuf/rpc/servers/zmq/broker_spec.rb +35 -0
  196. data/spec/lib/protobuf/rpc/servers/zmq/server_spec.rb +41 -0
  197. data/spec/lib/protobuf/rpc/servers/zmq/util_spec.rb +45 -0
  198. data/spec/lib/protobuf/rpc/servers/zmq/worker_spec.rb +44 -0
  199. data/spec/lib/protobuf/rpc/service_dispatcher_spec.rb +116 -0
  200. data/spec/lib/protobuf/rpc/service_filters_spec.rb +451 -0
  201. data/spec/lib/protobuf/rpc/service_spec.rb +165 -0
  202. data/spec/lib/protobuf_spec.rb +62 -0
  203. data/spec/spec_helper.rb +51 -0
  204. data/spec/support/all.rb +6 -0
  205. data/spec/support/server.rb +101 -0
  206. data/spec/support/test/enum.pb.rb +34 -0
  207. data/spec/support/test/enum.proto +12 -0
  208. data/spec/support/test/resource.pb.rb +58 -0
  209. data/spec/support/test/resource.proto +31 -0
  210. data/spec/support/test/resource_service.rb +14 -0
  211. data/spec/support/test_app_file.rb +2 -0
  212. data/spec/support/tolerance_matcher.rb +40 -0
  213. data/test/data/data.bin +3 -0
  214. data/test/data/data_source.py +14 -0
  215. data/test/data/types.bin +0 -0
  216. data/test/data/types_source.py +22 -0
  217. data/test/data/unk.png +0 -0
  218. data/test/proto/addressbook.pb.rb +66 -0
  219. data/test/proto/addressbook.proto +33 -0
  220. data/test/proto/addressbook_base.pb.rb +58 -0
  221. data/test/proto/addressbook_base.proto +26 -0
  222. data/test/proto/addressbook_ext.pb.rb +20 -0
  223. data/test/proto/addressbook_ext.proto +6 -0
  224. data/test/proto/collision.pb.rb +17 -0
  225. data/test/proto/collision.proto +5 -0
  226. data/test/proto/ext_collision.pb.rb +24 -0
  227. data/test/proto/ext_collision.proto +8 -0
  228. data/test/proto/ext_range.pb.rb +22 -0
  229. data/test/proto/ext_range.proto +7 -0
  230. data/test/proto/float_default.proto +10 -0
  231. data/test/proto/lowercase.pb.rb +30 -0
  232. data/test/proto/lowercase.proto +9 -0
  233. data/test/proto/merge.pb.rb +39 -0
  234. data/test/proto/merge.proto +15 -0
  235. data/test/proto/nested.pb.rb +30 -0
  236. data/test/proto/nested.proto +9 -0
  237. data/test/proto/optional_field.pb.rb +35 -0
  238. data/test/proto/optional_field.proto +12 -0
  239. data/test/proto/packed.pb.rb +22 -0
  240. data/test/proto/packed.proto +6 -0
  241. data/test/proto/rpc.proto +6 -0
  242. data/test/proto/types.pb.rb +84 -0
  243. data/test/proto/types.proto +37 -0
  244. data/test/test_addressbook.rb +56 -0
  245. data/test/test_enum_value.rb +41 -0
  246. data/test/test_extension.rb +36 -0
  247. data/test/test_lowercase.rb +11 -0
  248. data/test/test_message.rb +128 -0
  249. data/test/test_optional_field.rb +103 -0
  250. data/test/test_packed_field.rb +40 -0
  251. data/test/test_parse.rb +15 -0
  252. data/test/test_repeated_types.rb +132 -0
  253. data/test/test_serialize.rb +61 -0
  254. data/test/test_standard_message.rb +96 -0
  255. data/test/test_types.rb +226 -0
  256. metadata +461 -0
@@ -0,0 +1,1295 @@
1
+ // Protocol Buffers - Google's data interchange format
2
+ // Copyright 2008 Google Inc. All rights reserved.
3
+ // http://code.google.com/p/protobuf/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are
7
+ // met:
8
+ //
9
+ // * Redistributions of source code must retain the above copyright
10
+ // notice, this list of conditions and the following disclaimer.
11
+ // * Redistributions in binary form must reproduce the above
12
+ // copyright notice, this list of conditions and the following disclaimer
13
+ // in the documentation and/or other materials provided with the
14
+ // distribution.
15
+ // * Neither the name of Google Inc. nor the names of its
16
+ // contributors may be used to endorse or promote products derived from
17
+ // this software without specific prior written permission.
18
+ //
19
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
+ // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
+ // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
+ // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
+ // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
+ // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
+ // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
+ // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
+ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+
31
+ // Author: kenton@google.com (Kenton Varda)
32
+ // Based on original Protocol Buffers design by
33
+ // Sanjay Ghemawat, Jeff Dean, and others.
34
+ //
35
+ // RepeatedField and RepeatedPtrField are used by generated protocol message
36
+ // classes to manipulate repeated fields. These classes are very similar to
37
+ // STL's vector, but include a number of optimizations found to be useful
38
+ // specifically in the case of Protocol Buffers. RepeatedPtrField is
39
+ // particularly different from STL vector as it manages ownership of the
40
+ // pointers that it contains.
41
+ //
42
+ // Typically, clients should not need to access RepeatedField objects directly,
43
+ // but should instead use the accessor functions generated automatically by the
44
+ // protocol compiler.
45
+
46
+ #ifndef GOOGLE_PROTOBUF_REPEATED_FIELD_H__
47
+ #define GOOGLE_PROTOBUF_REPEATED_FIELD_H__
48
+
49
+ #include <string>
50
+ #include <iterator>
51
+ #include <google/protobuf/stubs/common.h>
52
+ #include <google/protobuf/message_lite.h>
53
+
54
+ namespace google {
55
+
56
+ namespace protobuf {
57
+
58
+ class Message;
59
+
60
+ namespace internal {
61
+
62
+ // We need this (from generated_message_reflection.cc).
63
+ LIBPROTOBUF_EXPORT int StringSpaceUsedExcludingSelf(const string& str);
64
+
65
+ } // namespace internal
66
+
67
+ // RepeatedField is used to represent repeated fields of a primitive type (in
68
+ // other words, everything except strings and nested Messages). Most users will
69
+ // not ever use a RepeatedField directly; they will use the get-by-index,
70
+ // set-by-index, and add accessors that are generated for all repeated fields.
71
+ template <typename Element>
72
+ class RepeatedField {
73
+ public:
74
+ RepeatedField();
75
+ RepeatedField(const RepeatedField& other);
76
+ ~RepeatedField();
77
+
78
+ RepeatedField& operator=(const RepeatedField& other);
79
+
80
+ int size() const;
81
+
82
+ const Element& Get(int index) const;
83
+ Element* Mutable(int index);
84
+ void Set(int index, const Element& value);
85
+ void Add(const Element& value);
86
+ Element* Add();
87
+ // Remove the last element in the array.
88
+ // We don't provide a way to remove any element other than the last
89
+ // because it invites inefficient use, such as O(n^2) filtering loops
90
+ // that should have been O(n). If you want to remove an element other
91
+ // than the last, the best way to do it is to re-arrange the elements
92
+ // so that the one you want removed is at the end, then call RemoveLast().
93
+ void RemoveLast();
94
+ void Clear();
95
+ void MergeFrom(const RepeatedField& other);
96
+ void CopyFrom(const RepeatedField& other);
97
+
98
+ // Reserve space to expand the field to at least the given size. If the
99
+ // array is grown, it will always be at least doubled in size.
100
+ void Reserve(int new_size);
101
+
102
+ // Resize the RepeatedField to a new, smaller size. This is O(1).
103
+ void Truncate(int new_size);
104
+
105
+ void AddAlreadyReserved(const Element& value);
106
+ Element* AddAlreadyReserved();
107
+ int Capacity() const;
108
+
109
+ // Gets the underlying array. This pointer is possibly invalidated by
110
+ // any add or remove operation.
111
+ Element* mutable_data();
112
+ const Element* data() const;
113
+
114
+ // Swap entire contents with "other".
115
+ void Swap(RepeatedField* other);
116
+
117
+ // Swap two elements.
118
+ void SwapElements(int index1, int index2);
119
+
120
+ // STL-like iterator support
121
+ typedef Element* iterator;
122
+ typedef const Element* const_iterator;
123
+ typedef Element value_type;
124
+
125
+ iterator begin();
126
+ const_iterator begin() const;
127
+ iterator end();
128
+ const_iterator end() const;
129
+
130
+ // Returns the number of bytes used by the repeated field, excluding
131
+ // sizeof(*this)
132
+ int SpaceUsedExcludingSelf() const;
133
+
134
+ private:
135
+ static const int kInitialSize = 4;
136
+
137
+ Element* elements_;
138
+ int current_size_;
139
+ int total_size_;
140
+
141
+ Element initial_space_[kInitialSize];
142
+
143
+ // Move the contents of |from| into |to|, possibly clobbering |from| in the
144
+ // process. For primitive types this is just a memcpy(), but it could be
145
+ // specialized for non-primitive types to, say, swap each element instead.
146
+ void MoveArray(Element to[], Element from[], int size);
147
+
148
+ // Copy the elements of |from| into |to|.
149
+ void CopyArray(Element to[], const Element from[], int size);
150
+ };
151
+
152
+ namespace internal {
153
+ template <typename It> class RepeatedPtrIterator;
154
+ template <typename It> class RepeatedPtrOverPtrsIterator;
155
+ } // namespace internal
156
+
157
+ namespace internal {
158
+
159
+ // This is the common base class for RepeatedPtrFields. It deals only in void*
160
+ // pointers. Users should not use this interface directly.
161
+ //
162
+ // The methods of this interface correspond to the methods of RepeatedPtrField,
163
+ // but may have a template argument called TypeHandler. Its signature is:
164
+ // class TypeHandler {
165
+ // public:
166
+ // typedef MyType Type;
167
+ // static Type* New();
168
+ // static void Delete(Type*);
169
+ // static void Clear(Type*);
170
+ // static void Merge(const Type& from, Type* to);
171
+ //
172
+ // // Only needs to be implemented if SpaceUsedExcludingSelf() is called.
173
+ // static int SpaceUsed(const Type&);
174
+ // };
175
+ class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase {
176
+ protected:
177
+ // The reflection implementation needs to call protected methods directly,
178
+ // reinterpreting pointers as being to Message instead of a specific Message
179
+ // subclass.
180
+ friend class GeneratedMessageReflection;
181
+
182
+ // ExtensionSet stores repeated message extensions as
183
+ // RepeatedPtrField<MessageLite>, but non-lite ExtensionSets need to
184
+ // implement SpaceUsed(), and thus need to call SpaceUsedExcludingSelf()
185
+ // reinterpreting MessageLite as Message. ExtensionSet also needs to make
186
+ // use of AddFromCleared(), which is not part of the public interface.
187
+ friend class ExtensionSet;
188
+
189
+ RepeatedPtrFieldBase();
190
+
191
+ // Must be called from destructor.
192
+ template <typename TypeHandler>
193
+ void Destroy();
194
+
195
+ int size() const;
196
+
197
+ template <typename TypeHandler>
198
+ const typename TypeHandler::Type& Get(int index) const;
199
+ template <typename TypeHandler>
200
+ typename TypeHandler::Type* Mutable(int index);
201
+ template <typename TypeHandler>
202
+ typename TypeHandler::Type* Add();
203
+ template <typename TypeHandler>
204
+ void RemoveLast();
205
+ template <typename TypeHandler>
206
+ void Clear();
207
+ template <typename TypeHandler>
208
+ void MergeFrom(const RepeatedPtrFieldBase& other);
209
+ template <typename TypeHandler>
210
+ void CopyFrom(const RepeatedPtrFieldBase& other);
211
+
212
+ void Reserve(int new_size);
213
+
214
+ int Capacity() const;
215
+
216
+ // Used for constructing iterators.
217
+ void* const* raw_data() const;
218
+ void** raw_mutable_data() const;
219
+
220
+ template <typename TypeHandler>
221
+ typename TypeHandler::Type** mutable_data();
222
+ template <typename TypeHandler>
223
+ const typename TypeHandler::Type* const* data() const;
224
+
225
+ void Swap(RepeatedPtrFieldBase* other);
226
+
227
+ void SwapElements(int index1, int index2);
228
+
229
+ template <typename TypeHandler>
230
+ int SpaceUsedExcludingSelf() const;
231
+
232
+
233
+ // Advanced memory management --------------------------------------
234
+
235
+ // Like Add(), but if there are no cleared objects to use, returns NULL.
236
+ template <typename TypeHandler>
237
+ typename TypeHandler::Type* AddFromCleared();
238
+
239
+ template <typename TypeHandler>
240
+ void AddAllocated(typename TypeHandler::Type* value);
241
+ template <typename TypeHandler>
242
+ typename TypeHandler::Type* ReleaseLast();
243
+
244
+ int ClearedCount() const;
245
+ template <typename TypeHandler>
246
+ void AddCleared(typename TypeHandler::Type* value);
247
+ template <typename TypeHandler>
248
+ typename TypeHandler::Type* ReleaseCleared();
249
+
250
+ private:
251
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPtrFieldBase);
252
+
253
+ static const int kInitialSize = 4;
254
+
255
+ void** elements_;
256
+ int current_size_;
257
+ int allocated_size_;
258
+ int total_size_;
259
+
260
+ void* initial_space_[kInitialSize];
261
+
262
+ template <typename TypeHandler>
263
+ static inline typename TypeHandler::Type* cast(void* element) {
264
+ return reinterpret_cast<typename TypeHandler::Type*>(element);
265
+ }
266
+ template <typename TypeHandler>
267
+ static inline const typename TypeHandler::Type* cast(const void* element) {
268
+ return reinterpret_cast<const typename TypeHandler::Type*>(element);
269
+ }
270
+ };
271
+
272
+ template <typename GenericType>
273
+ class GenericTypeHandler {
274
+ public:
275
+ typedef GenericType Type;
276
+ static GenericType* New() { return new GenericType; }
277
+ static void Delete(GenericType* value) { delete value; }
278
+ static void Clear(GenericType* value) { value->Clear(); }
279
+ static void Merge(const GenericType& from, GenericType* to) {
280
+ to->MergeFrom(from);
281
+ }
282
+ static int SpaceUsed(const GenericType& value) { return value.SpaceUsed(); }
283
+ };
284
+
285
+ template <>
286
+ inline void GenericTypeHandler<MessageLite>::Merge(
287
+ const MessageLite& from, MessageLite* to) {
288
+ to->CheckTypeAndMergeFrom(from);
289
+ }
290
+
291
+ // HACK: If a class is declared as DLL-exported in MSVC, it insists on
292
+ // generating copies of all its methods -- even inline ones -- to include
293
+ // in the DLL. But SpaceUsed() calls StringSpaceUsedExcludingSelf() which
294
+ // isn't in the lite library, therefore the lite library cannot link if
295
+ // StringTypeHandler is exported. So, we factor out StringTypeHandlerBase,
296
+ // export that, then make StringTypeHandler be a subclass which is NOT
297
+ // exported.
298
+ // TODO(kenton): There has to be a better way.
299
+ class LIBPROTOBUF_EXPORT StringTypeHandlerBase {
300
+ public:
301
+ typedef string Type;
302
+ static string* New();
303
+ static void Delete(string* value);
304
+ static void Clear(string* value) { value->clear(); }
305
+ static void Merge(const string& from, string* to) { *to = from; }
306
+ };
307
+
308
+ class LIBPROTOBUF_EXPORT StringTypeHandler : public StringTypeHandlerBase {
309
+ public:
310
+ static int SpaceUsed(const string& value) {
311
+ return sizeof(value) + StringSpaceUsedExcludingSelf(value);
312
+ }
313
+ };
314
+
315
+
316
+ } // namespace internal
317
+
318
+ // RepeatedPtrField is like RepeatedField, but used for repeated strings or
319
+ // Messages.
320
+ template <typename Element>
321
+ class RepeatedPtrField : public internal::RepeatedPtrFieldBase {
322
+ public:
323
+ RepeatedPtrField();
324
+ RepeatedPtrField(const RepeatedPtrField& other);
325
+ ~RepeatedPtrField();
326
+
327
+ RepeatedPtrField& operator=(const RepeatedPtrField& other);
328
+
329
+ int size() const;
330
+
331
+ const Element& Get(int index) const;
332
+ Element* Mutable(int index);
333
+ Element* Add();
334
+ void RemoveLast(); // Remove the last element in the array.
335
+ void Clear();
336
+ void MergeFrom(const RepeatedPtrField& other);
337
+ void CopyFrom(const RepeatedPtrField& other);
338
+
339
+ // Reserve space to expand the field to at least the given size. This only
340
+ // resizes the pointer array; it doesn't allocate any objects. If the
341
+ // array is grown, it will always be at least doubled in size.
342
+ void Reserve(int new_size);
343
+
344
+ int Capacity() const;
345
+
346
+ // Gets the underlying array. This pointer is possibly invalidated by
347
+ // any add or remove operation.
348
+ Element** mutable_data();
349
+ const Element* const* data() const;
350
+
351
+ // Swap entire contents with "other".
352
+ void Swap(RepeatedPtrField* other);
353
+
354
+ // Swap two elements.
355
+ void SwapElements(int index1, int index2);
356
+
357
+ // STL-like iterator support
358
+ typedef internal::RepeatedPtrIterator<Element> iterator;
359
+ typedef internal::RepeatedPtrIterator<const Element> const_iterator;
360
+ typedef Element value_type;
361
+
362
+ iterator begin();
363
+ const_iterator begin() const;
364
+ iterator end();
365
+ const_iterator end() const;
366
+
367
+ // Custom STL-like iterator that iterates over and returns the underlying
368
+ // pointers to Element rather than Element itself.
369
+ typedef internal::RepeatedPtrOverPtrsIterator<Element> pointer_iterator;
370
+ pointer_iterator pointer_begin();
371
+ pointer_iterator pointer_end();
372
+
373
+ // Returns (an estimate of) the number of bytes used by the repeated field,
374
+ // excluding sizeof(*this).
375
+ int SpaceUsedExcludingSelf() const;
376
+
377
+ // Advanced memory management --------------------------------------
378
+ // When hardcore memory management becomes necessary -- as it often
379
+ // does here at Google -- the following methods may be useful.
380
+
381
+ // Add an already-allocated object, passing ownership to the
382
+ // RepeatedPtrField.
383
+ void AddAllocated(Element* value);
384
+ // Remove the last element and return it, passing ownership to the
385
+ // caller.
386
+ // Requires: size() > 0
387
+ Element* ReleaseLast();
388
+
389
+ // When elements are removed by calls to RemoveLast() or Clear(), they
390
+ // are not actually freed. Instead, they are cleared and kept so that
391
+ // they can be reused later. This can save lots of CPU time when
392
+ // repeatedly reusing a protocol message for similar purposes.
393
+ //
394
+ // Really, extremely hardcore programs may actually want to manipulate
395
+ // these objects to better-optimize memory management. These methods
396
+ // allow that.
397
+
398
+ // Get the number of cleared objects that are currently being kept
399
+ // around for reuse.
400
+ int ClearedCount() const;
401
+ // Add an element to the pool of cleared objects, passing ownership to
402
+ // the RepeatedPtrField. The element must be cleared prior to calling
403
+ // this method.
404
+ void AddCleared(Element* value);
405
+ // Remove a single element from the cleared pool and return it, passing
406
+ // ownership to the caller. The element is guaranteed to be cleared.
407
+ // Requires: ClearedCount() > 0
408
+ Element* ReleaseCleared();
409
+
410
+ protected:
411
+ // Note: RepeatedPtrField SHOULD NOT be subclassed by users. We only
412
+ // subclass it in one place as a hack for compatibility with proto1. The
413
+ // subclass needs to know about TypeHandler in order to call protected
414
+ // methods on RepeatedPtrFieldBase.
415
+ class TypeHandler;
416
+
417
+ };
418
+
419
+ // implementation ====================================================
420
+
421
+ template <typename Element>
422
+ inline RepeatedField<Element>::RepeatedField()
423
+ : elements_(initial_space_),
424
+ current_size_(0),
425
+ total_size_(kInitialSize) {
426
+ }
427
+
428
+ template <typename Element>
429
+ inline RepeatedField<Element>::RepeatedField(const RepeatedField& other)
430
+ : elements_(initial_space_),
431
+ current_size_(0),
432
+ total_size_(kInitialSize) {
433
+ CopyFrom(other);
434
+ }
435
+
436
+ template <typename Element>
437
+ RepeatedField<Element>::~RepeatedField() {
438
+ if (elements_ != initial_space_) {
439
+ delete [] elements_;
440
+ }
441
+ }
442
+
443
+ template <typename Element>
444
+ inline RepeatedField<Element>&
445
+ RepeatedField<Element>::operator=(const RepeatedField& other) {
446
+ CopyFrom(other);
447
+ return *this;
448
+ }
449
+
450
+ template <typename Element>
451
+ inline int RepeatedField<Element>::size() const {
452
+ return current_size_;
453
+ }
454
+
455
+ template <typename Element>
456
+ inline int RepeatedField<Element>::Capacity() const {
457
+ return total_size_;
458
+ }
459
+
460
+ template<typename Element>
461
+ inline void RepeatedField<Element>::AddAlreadyReserved(const Element& value) {
462
+ GOOGLE_DCHECK_LT(size(), Capacity());
463
+ elements_[current_size_++] = value;
464
+ }
465
+
466
+ template<typename Element>
467
+ inline Element* RepeatedField<Element>::AddAlreadyReserved() {
468
+ GOOGLE_DCHECK_LT(size(), Capacity());
469
+ return &elements_[current_size_++];
470
+ }
471
+
472
+ template <typename Element>
473
+ inline const Element& RepeatedField<Element>::Get(int index) const {
474
+ GOOGLE_DCHECK_LT(index, size());
475
+ return elements_[index];
476
+ }
477
+
478
+ template <typename Element>
479
+ inline Element* RepeatedField<Element>::Mutable(int index) {
480
+ GOOGLE_DCHECK_LT(index, size());
481
+ return elements_ + index;
482
+ }
483
+
484
+ template <typename Element>
485
+ inline void RepeatedField<Element>::Set(int index, const Element& value) {
486
+ GOOGLE_DCHECK_LT(index, size());
487
+ elements_[index] = value;
488
+ }
489
+
490
+ template <typename Element>
491
+ inline void RepeatedField<Element>::Add(const Element& value) {
492
+ if (current_size_ == total_size_) Reserve(total_size_ + 1);
493
+ elements_[current_size_++] = value;
494
+ }
495
+
496
+ template <typename Element>
497
+ inline Element* RepeatedField<Element>::Add() {
498
+ if (current_size_ == total_size_) Reserve(total_size_ + 1);
499
+ return &elements_[current_size_++];
500
+ }
501
+
502
+ template <typename Element>
503
+ inline void RepeatedField<Element>::RemoveLast() {
504
+ GOOGLE_DCHECK_GT(current_size_, 0);
505
+ --current_size_;
506
+ }
507
+
508
+ template <typename Element>
509
+ inline void RepeatedField<Element>::Clear() {
510
+ current_size_ = 0;
511
+ }
512
+
513
+ template <typename Element>
514
+ inline void RepeatedField<Element>::MergeFrom(const RepeatedField& other) {
515
+ Reserve(current_size_ + other.current_size_);
516
+ CopyArray(elements_ + current_size_, other.elements_, other.current_size_);
517
+ current_size_ += other.current_size_;
518
+ }
519
+
520
+ template <typename Element>
521
+ inline void RepeatedField<Element>::CopyFrom(const RepeatedField& other) {
522
+ Clear();
523
+ MergeFrom(other);
524
+ }
525
+
526
+ template <typename Element>
527
+ inline Element* RepeatedField<Element>::mutable_data() {
528
+ return elements_;
529
+ }
530
+
531
+ template <typename Element>
532
+ inline const Element* RepeatedField<Element>::data() const {
533
+ return elements_;
534
+ }
535
+
536
+
537
+ template <typename Element>
538
+ void RepeatedField<Element>::Swap(RepeatedField* other) {
539
+ Element* swap_elements = elements_;
540
+ int swap_current_size = current_size_;
541
+ int swap_total_size = total_size_;
542
+ // We may not be using initial_space_ but it's not worth checking. Just
543
+ // copy it anyway.
544
+ Element swap_initial_space[kInitialSize];
545
+ MoveArray(swap_initial_space, initial_space_, kInitialSize);
546
+
547
+ elements_ = other->elements_;
548
+ current_size_ = other->current_size_;
549
+ total_size_ = other->total_size_;
550
+ MoveArray(initial_space_, other->initial_space_, kInitialSize);
551
+
552
+ other->elements_ = swap_elements;
553
+ other->current_size_ = swap_current_size;
554
+ other->total_size_ = swap_total_size;
555
+ MoveArray(other->initial_space_, swap_initial_space, kInitialSize);
556
+
557
+ if (elements_ == other->initial_space_) {
558
+ elements_ = initial_space_;
559
+ }
560
+ if (other->elements_ == initial_space_) {
561
+ other->elements_ = other->initial_space_;
562
+ }
563
+ }
564
+
565
+ template <typename Element>
566
+ void RepeatedField<Element>::SwapElements(int index1, int index2) {
567
+ std::swap(elements_[index1], elements_[index2]);
568
+ }
569
+
570
+ template <typename Element>
571
+ inline typename RepeatedField<Element>::iterator
572
+ RepeatedField<Element>::begin() {
573
+ return elements_;
574
+ }
575
+ template <typename Element>
576
+ inline typename RepeatedField<Element>::const_iterator
577
+ RepeatedField<Element>::begin() const {
578
+ return elements_;
579
+ }
580
+ template <typename Element>
581
+ inline typename RepeatedField<Element>::iterator
582
+ RepeatedField<Element>::end() {
583
+ return elements_ + current_size_;
584
+ }
585
+ template <typename Element>
586
+ inline typename RepeatedField<Element>::const_iterator
587
+ RepeatedField<Element>::end() const {
588
+ return elements_ + current_size_;
589
+ }
590
+
591
+ template <typename Element>
592
+ inline int RepeatedField<Element>::SpaceUsedExcludingSelf() const {
593
+ return (elements_ != initial_space_) ? total_size_ * sizeof(elements_[0]) : 0;
594
+ }
595
+
596
+ // Avoid inlining of Reserve(): new, memcpy, and delete[] lead to a significant
597
+ // amount of code bloat.
598
+ template <typename Element>
599
+ void RepeatedField<Element>::Reserve(int new_size) {
600
+ if (total_size_ >= new_size) return;
601
+
602
+ Element* old_elements = elements_;
603
+ total_size_ = max(total_size_ * 2, new_size);
604
+ elements_ = new Element[total_size_];
605
+ MoveArray(elements_, old_elements, current_size_);
606
+ if (old_elements != initial_space_) {
607
+ delete [] old_elements;
608
+ }
609
+ }
610
+
611
+ template <typename Element>
612
+ inline void RepeatedField<Element>::Truncate(int new_size) {
613
+ GOOGLE_DCHECK_LE(new_size, current_size_);
614
+ current_size_ = new_size;
615
+ }
616
+
617
+ template <typename Element>
618
+ inline void RepeatedField<Element>::MoveArray(
619
+ Element to[], Element from[], int array_size) {
620
+ memcpy(to, from, array_size * sizeof(Element));
621
+ }
622
+
623
+ template <typename Element>
624
+ inline void RepeatedField<Element>::CopyArray(
625
+ Element to[], const Element from[], int array_size) {
626
+ memcpy(to, from, array_size * sizeof(Element));
627
+ }
628
+
629
+
630
+ // -------------------------------------------------------------------
631
+
632
+ namespace internal {
633
+
634
+ inline RepeatedPtrFieldBase::RepeatedPtrFieldBase()
635
+ : elements_(initial_space_),
636
+ current_size_(0),
637
+ allocated_size_(0),
638
+ total_size_(kInitialSize) {
639
+ }
640
+
641
+ template <typename TypeHandler>
642
+ void RepeatedPtrFieldBase::Destroy() {
643
+ for (int i = 0; i < allocated_size_; i++) {
644
+ TypeHandler::Delete(cast<TypeHandler>(elements_[i]));
645
+ }
646
+ if (elements_ != initial_space_) {
647
+ delete [] elements_;
648
+ }
649
+ }
650
+
651
+ inline int RepeatedPtrFieldBase::size() const {
652
+ return current_size_;
653
+ }
654
+
655
+
656
+ template <typename TypeHandler>
657
+ inline const typename TypeHandler::Type&
658
+ RepeatedPtrFieldBase::Get(int index) const {
659
+ GOOGLE_DCHECK_LT(index, size());
660
+ return *cast<TypeHandler>(elements_[index]);
661
+ }
662
+
663
+ template <typename TypeHandler>
664
+ inline typename TypeHandler::Type*
665
+ RepeatedPtrFieldBase::Mutable(int index) {
666
+ GOOGLE_DCHECK_LT(index, size());
667
+ return cast<TypeHandler>(elements_[index]);
668
+ }
669
+
670
+ template <typename TypeHandler>
671
+ inline typename TypeHandler::Type* RepeatedPtrFieldBase::Add() {
672
+ if (current_size_ < allocated_size_) {
673
+ return cast<TypeHandler>(elements_[current_size_++]);
674
+ }
675
+ if (allocated_size_ == total_size_) Reserve(total_size_ + 1);
676
+ ++allocated_size_;
677
+ typename TypeHandler::Type* result = TypeHandler::New();
678
+ elements_[current_size_++] = result;
679
+ return result;
680
+ }
681
+
682
+ template <typename TypeHandler>
683
+ inline void RepeatedPtrFieldBase::RemoveLast() {
684
+ GOOGLE_DCHECK_GT(current_size_, 0);
685
+ TypeHandler::Clear(cast<TypeHandler>(elements_[--current_size_]));
686
+ }
687
+
688
+ template <typename TypeHandler>
689
+ void RepeatedPtrFieldBase::Clear() {
690
+ for (int i = 0; i < current_size_; i++) {
691
+ TypeHandler::Clear(cast<TypeHandler>(elements_[i]));
692
+ }
693
+ current_size_ = 0;
694
+ }
695
+
696
+ template <typename TypeHandler>
697
+ inline void RepeatedPtrFieldBase::MergeFrom(const RepeatedPtrFieldBase& other) {
698
+ Reserve(current_size_ + other.current_size_);
699
+ for (int i = 0; i < other.current_size_; i++) {
700
+ TypeHandler::Merge(other.template Get<TypeHandler>(i), Add<TypeHandler>());
701
+ }
702
+ }
703
+
704
+ template <typename TypeHandler>
705
+ inline void RepeatedPtrFieldBase::CopyFrom(const RepeatedPtrFieldBase& other) {
706
+ RepeatedPtrFieldBase::Clear<TypeHandler>();
707
+ RepeatedPtrFieldBase::MergeFrom<TypeHandler>(other);
708
+ }
709
+
710
+ inline int RepeatedPtrFieldBase::Capacity() const {
711
+ return total_size_;
712
+ }
713
+
714
+ inline void* const* RepeatedPtrFieldBase::raw_data() const {
715
+ return elements_;
716
+ }
717
+
718
+ inline void** RepeatedPtrFieldBase::raw_mutable_data() const {
719
+ return elements_;
720
+ }
721
+
722
+ template <typename TypeHandler>
723
+ inline typename TypeHandler::Type** RepeatedPtrFieldBase::mutable_data() {
724
+ // TODO(kenton): Breaks C++ aliasing rules. We should probably remove this
725
+ // method entirely.
726
+ return reinterpret_cast<typename TypeHandler::Type**>(elements_);
727
+ }
728
+
729
+ template <typename TypeHandler>
730
+ inline const typename TypeHandler::Type* const*
731
+ RepeatedPtrFieldBase::data() const {
732
+ // TODO(kenton): Breaks C++ aliasing rules. We should probably remove this
733
+ // method entirely.
734
+ return reinterpret_cast<const typename TypeHandler::Type* const*>(elements_);
735
+ }
736
+
737
+ inline void RepeatedPtrFieldBase::SwapElements(int index1, int index2) {
738
+ std::swap(elements_[index1], elements_[index2]);
739
+ }
740
+
741
+ template <typename TypeHandler>
742
+ inline int RepeatedPtrFieldBase::SpaceUsedExcludingSelf() const {
743
+ int allocated_bytes =
744
+ (elements_ != initial_space_) ? total_size_ * sizeof(elements_[0]) : 0;
745
+ for (int i = 0; i < allocated_size_; ++i) {
746
+ allocated_bytes += TypeHandler::SpaceUsed(*cast<TypeHandler>(elements_[i]));
747
+ }
748
+ return allocated_bytes;
749
+ }
750
+
751
+ template <typename TypeHandler>
752
+ inline typename TypeHandler::Type* RepeatedPtrFieldBase::AddFromCleared() {
753
+ if (current_size_ < allocated_size_) {
754
+ return cast<TypeHandler>(elements_[current_size_++]);
755
+ } else {
756
+ return NULL;
757
+ }
758
+ }
759
+
760
+ template <typename TypeHandler>
761
+ void RepeatedPtrFieldBase::AddAllocated(
762
+ typename TypeHandler::Type* value) {
763
+ // Make room for the new pointer.
764
+ if (current_size_ == total_size_) {
765
+ // The array is completely full with no cleared objects, so grow it.
766
+ Reserve(total_size_ + 1);
767
+ ++allocated_size_;
768
+ } else if (allocated_size_ == total_size_) {
769
+ // There is no more space in the pointer array because it contains some
770
+ // cleared objects awaiting reuse. We don't want to grow the array in this
771
+ // case because otherwise a loop calling AddAllocated() followed by Clear()
772
+ // would leak memory.
773
+ TypeHandler::Delete(cast<TypeHandler>(elements_[current_size_]));
774
+ } else if (current_size_ < allocated_size_) {
775
+ // We have some cleared objects. We don't care about their order, so we
776
+ // can just move the first one to the end to make space.
777
+ elements_[allocated_size_] = elements_[current_size_];
778
+ ++allocated_size_;
779
+ } else {
780
+ // There are no cleared objects.
781
+ ++allocated_size_;
782
+ }
783
+
784
+ elements_[current_size_++] = value;
785
+ }
786
+
787
+ template <typename TypeHandler>
788
+ inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseLast() {
789
+ GOOGLE_DCHECK_GT(current_size_, 0);
790
+ typename TypeHandler::Type* result =
791
+ cast<TypeHandler>(elements_[--current_size_]);
792
+ --allocated_size_;
793
+ if (current_size_ < allocated_size_) {
794
+ // There are cleared elements on the end; replace the removed element
795
+ // with the last allocated element.
796
+ elements_[current_size_] = elements_[allocated_size_];
797
+ }
798
+ return result;
799
+ }
800
+
801
+
802
+ inline int RepeatedPtrFieldBase::ClearedCount() const {
803
+ return allocated_size_ - current_size_;
804
+ }
805
+
806
+ template <typename TypeHandler>
807
+ inline void RepeatedPtrFieldBase::AddCleared(
808
+ typename TypeHandler::Type* value) {
809
+ if (allocated_size_ == total_size_) Reserve(total_size_ + 1);
810
+ elements_[allocated_size_++] = value;
811
+ }
812
+
813
+ template <typename TypeHandler>
814
+ inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseCleared() {
815
+ GOOGLE_DCHECK_GT(allocated_size_, current_size_);
816
+ return cast<TypeHandler>(elements_[--allocated_size_]);
817
+ }
818
+
819
+ } // namespace internal
820
+
821
+ // -------------------------------------------------------------------
822
+
823
+ template <typename Element>
824
+ class RepeatedPtrField<Element>::TypeHandler
825
+ : public internal::GenericTypeHandler<Element> {};
826
+
827
+ template <>
828
+ class RepeatedPtrField<string>::TypeHandler
829
+ : public internal::StringTypeHandler {};
830
+
831
+
832
+ template <typename Element>
833
+ inline RepeatedPtrField<Element>::RepeatedPtrField() {}
834
+
835
+ template <typename Element>
836
+ inline RepeatedPtrField<Element>::RepeatedPtrField(
837
+ const RepeatedPtrField& other) {
838
+ CopyFrom(other);
839
+ }
840
+
841
+ template <typename Element>
842
+ RepeatedPtrField<Element>::~RepeatedPtrField() {
843
+ Destroy<TypeHandler>();
844
+ }
845
+
846
+ template <typename Element>
847
+ inline RepeatedPtrField<Element>& RepeatedPtrField<Element>::operator=(
848
+ const RepeatedPtrField& other) {
849
+ CopyFrom(other);
850
+ return *this;
851
+ }
852
+
853
+ template <typename Element>
854
+ inline int RepeatedPtrField<Element>::size() const {
855
+ return RepeatedPtrFieldBase::size();
856
+ }
857
+
858
+ template <typename Element>
859
+ inline const Element& RepeatedPtrField<Element>::Get(int index) const {
860
+ return RepeatedPtrFieldBase::Get<TypeHandler>(index);
861
+ }
862
+
863
+ template <typename Element>
864
+ inline Element* RepeatedPtrField<Element>::Mutable(int index) {
865
+ return RepeatedPtrFieldBase::Mutable<TypeHandler>(index);
866
+ }
867
+
868
+ template <typename Element>
869
+ inline Element* RepeatedPtrField<Element>::Add() {
870
+ return RepeatedPtrFieldBase::Add<TypeHandler>();
871
+ }
872
+
873
+ template <typename Element>
874
+ inline void RepeatedPtrField<Element>::RemoveLast() {
875
+ RepeatedPtrFieldBase::RemoveLast<TypeHandler>();
876
+ }
877
+
878
+ template <typename Element>
879
+ inline void RepeatedPtrField<Element>::Clear() {
880
+ RepeatedPtrFieldBase::Clear<TypeHandler>();
881
+ }
882
+
883
+ template <typename Element>
884
+ inline void RepeatedPtrField<Element>::MergeFrom(
885
+ const RepeatedPtrField& other) {
886
+ RepeatedPtrFieldBase::MergeFrom<TypeHandler>(other);
887
+ }
888
+
889
+ template <typename Element>
890
+ inline void RepeatedPtrField<Element>::CopyFrom(
891
+ const RepeatedPtrField& other) {
892
+ RepeatedPtrFieldBase::CopyFrom<TypeHandler>(other);
893
+ }
894
+
895
+ template <typename Element>
896
+ inline Element** RepeatedPtrField<Element>::mutable_data() {
897
+ return RepeatedPtrFieldBase::mutable_data<TypeHandler>();
898
+ }
899
+
900
+ template <typename Element>
901
+ inline const Element* const* RepeatedPtrField<Element>::data() const {
902
+ return RepeatedPtrFieldBase::data<TypeHandler>();
903
+ }
904
+
905
+ template <typename Element>
906
+ void RepeatedPtrField<Element>::Swap(RepeatedPtrField* other) {
907
+ RepeatedPtrFieldBase::Swap(other);
908
+ }
909
+
910
+ template <typename Element>
911
+ void RepeatedPtrField<Element>::SwapElements(int index1, int index2) {
912
+ RepeatedPtrFieldBase::SwapElements(index1, index2);
913
+ }
914
+
915
+ template <typename Element>
916
+ inline int RepeatedPtrField<Element>::SpaceUsedExcludingSelf() const {
917
+ return RepeatedPtrFieldBase::SpaceUsedExcludingSelf<TypeHandler>();
918
+ }
919
+
920
+ template <typename Element>
921
+ inline void RepeatedPtrField<Element>::AddAllocated(Element* value) {
922
+ RepeatedPtrFieldBase::AddAllocated<TypeHandler>(value);
923
+ }
924
+
925
+ template <typename Element>
926
+ inline Element* RepeatedPtrField<Element>::ReleaseLast() {
927
+ return RepeatedPtrFieldBase::ReleaseLast<TypeHandler>();
928
+ }
929
+
930
+
931
+ template <typename Element>
932
+ inline int RepeatedPtrField<Element>::ClearedCount() const {
933
+ return RepeatedPtrFieldBase::ClearedCount();
934
+ }
935
+
936
+ template <typename Element>
937
+ inline void RepeatedPtrField<Element>::AddCleared(Element* value) {
938
+ return RepeatedPtrFieldBase::AddCleared<TypeHandler>(value);
939
+ }
940
+
941
+ template <typename Element>
942
+ inline Element* RepeatedPtrField<Element>::ReleaseCleared() {
943
+ return RepeatedPtrFieldBase::ReleaseCleared<TypeHandler>();
944
+ }
945
+
946
+ template <typename Element>
947
+ inline void RepeatedPtrField<Element>::Reserve(int new_size) {
948
+ return RepeatedPtrFieldBase::Reserve(new_size);
949
+ }
950
+
951
+ template <typename Element>
952
+ inline int RepeatedPtrField<Element>::Capacity() const {
953
+ return RepeatedPtrFieldBase::Capacity();
954
+ }
955
+
956
+ // -------------------------------------------------------------------
957
+
958
+ namespace internal {
959
+
960
+ // STL-like iterator implementation for RepeatedPtrField. You should not
961
+ // refer to this class directly; use RepeatedPtrField<T>::iterator instead.
962
+ //
963
+ // The iterator for RepeatedPtrField<T>, RepeatedPtrIterator<T>, is
964
+ // very similar to iterator_ptr<T**> in util/gtl/iterator_adaptors-inl.h,
965
+ // but adds random-access operators and is modified to wrap a void** base
966
+ // iterator (since RepeatedPtrField stores its array as a void* array and
967
+ // casting void** to T** would violate C++ aliasing rules).
968
+ //
969
+ // This code based on net/proto/proto-array-internal.h by Jeffrey Yasskin
970
+ // (jyasskin@google.com).
971
+ template<typename Element>
972
+ class RepeatedPtrIterator
973
+ : public std::iterator<
974
+ std::random_access_iterator_tag, Element> {
975
+ public:
976
+ typedef RepeatedPtrIterator<Element> iterator;
977
+ typedef std::iterator<
978
+ std::random_access_iterator_tag, Element> superclass;
979
+
980
+ // Let the compiler know that these are type names, so we don't have to
981
+ // write "typename" in front of them everywhere.
982
+ typedef typename superclass::reference reference;
983
+ typedef typename superclass::pointer pointer;
984
+ typedef typename superclass::difference_type difference_type;
985
+
986
+ RepeatedPtrIterator() : it_(NULL) {}
987
+ explicit RepeatedPtrIterator(void* const* it) : it_(it) {}
988
+
989
+ // Allow "upcasting" from RepeatedPtrIterator<T**> to
990
+ // RepeatedPtrIterator<const T*const*>.
991
+ template<typename OtherElement>
992
+ RepeatedPtrIterator(const RepeatedPtrIterator<OtherElement>& other)
993
+ : it_(other.it_) {
994
+ // Force a compiler error if the other type is not convertible to ours.
995
+ if (false) {
996
+ implicit_cast<Element*, OtherElement*>(0);
997
+ }
998
+ }
999
+
1000
+ // dereferenceable
1001
+ reference operator*() const { return *reinterpret_cast<Element*>(*it_); }
1002
+ pointer operator->() const { return &(operator*()); }
1003
+
1004
+ // {inc,dec}rementable
1005
+ iterator& operator++() { ++it_; return *this; }
1006
+ iterator operator++(int) { return iterator(it_++); }
1007
+ iterator& operator--() { --it_; return *this; }
1008
+ iterator operator--(int) { return iterator(it_--); }
1009
+
1010
+ // equality_comparable
1011
+ bool operator==(const iterator& x) const { return it_ == x.it_; }
1012
+ bool operator!=(const iterator& x) const { return it_ != x.it_; }
1013
+
1014
+ // less_than_comparable
1015
+ bool operator<(const iterator& x) const { return it_ < x.it_; }
1016
+ bool operator<=(const iterator& x) const { return it_ <= x.it_; }
1017
+ bool operator>(const iterator& x) const { return it_ > x.it_; }
1018
+ bool operator>=(const iterator& x) const { return it_ >= x.it_; }
1019
+
1020
+ // addable, subtractable
1021
+ iterator& operator+=(difference_type d) {
1022
+ it_ += d;
1023
+ return *this;
1024
+ }
1025
+ friend iterator operator+(iterator it, difference_type d) {
1026
+ it += d;
1027
+ return it;
1028
+ }
1029
+ friend iterator operator+(difference_type d, iterator it) {
1030
+ it += d;
1031
+ return it;
1032
+ }
1033
+ iterator& operator-=(difference_type d) {
1034
+ it_ -= d;
1035
+ return *this;
1036
+ }
1037
+ friend iterator operator-(iterator it, difference_type d) {
1038
+ it -= d;
1039
+ return it;
1040
+ }
1041
+
1042
+ // indexable
1043
+ reference operator[](difference_type d) const { return *(*this + d); }
1044
+
1045
+ // random access iterator
1046
+ difference_type operator-(const iterator& x) const { return it_ - x.it_; }
1047
+
1048
+ private:
1049
+ template<typename OtherElement>
1050
+ friend class RepeatedPtrIterator;
1051
+
1052
+ // The internal iterator.
1053
+ void* const* it_;
1054
+ };
1055
+
1056
+ // Provide an iterator that operates on pointers to the underlying objects
1057
+ // rather than the objects themselves as RepeatedPtrIterator does.
1058
+ // Consider using this when working with stl algorithms that change
1059
+ // the array.
1060
+ template<typename Element>
1061
+ class RepeatedPtrOverPtrsIterator
1062
+ : public std::iterator<std::random_access_iterator_tag, Element*> {
1063
+ public:
1064
+ typedef RepeatedPtrOverPtrsIterator<Element> iterator;
1065
+ typedef std::iterator<
1066
+ std::random_access_iterator_tag, Element*> superclass;
1067
+
1068
+ // Let the compiler know that these are type names, so we don't have to
1069
+ // write "typename" in front of them everywhere.
1070
+ typedef typename superclass::reference reference;
1071
+ typedef typename superclass::pointer pointer;
1072
+ typedef typename superclass::difference_type difference_type;
1073
+
1074
+ RepeatedPtrOverPtrsIterator() : it_(NULL) {}
1075
+ explicit RepeatedPtrOverPtrsIterator(void** it) : it_(it) {}
1076
+
1077
+ // dereferenceable
1078
+ reference operator*() const { return *reinterpret_cast<Element**>(it_); }
1079
+ pointer operator->() const { return &(operator*()); }
1080
+
1081
+ // {inc,dec}rementable
1082
+ iterator& operator++() { ++it_; return *this; }
1083
+ iterator operator++(int) { return iterator(it_++); }
1084
+ iterator& operator--() { --it_; return *this; }
1085
+ iterator operator--(int) { return iterator(it_--); }
1086
+
1087
+ // equality_comparable
1088
+ bool operator==(const iterator& x) const { return it_ == x.it_; }
1089
+ bool operator!=(const iterator& x) const { return it_ != x.it_; }
1090
+
1091
+ // less_than_comparable
1092
+ bool operator<(const iterator& x) const { return it_ < x.it_; }
1093
+ bool operator<=(const iterator& x) const { return it_ <= x.it_; }
1094
+ bool operator>(const iterator& x) const { return it_ > x.it_; }
1095
+ bool operator>=(const iterator& x) const { return it_ >= x.it_; }
1096
+
1097
+ // addable, subtractable
1098
+ iterator& operator+=(difference_type d) {
1099
+ it_ += d;
1100
+ return *this;
1101
+ }
1102
+ friend iterator operator+(iterator it, difference_type d) {
1103
+ it += d;
1104
+ return it;
1105
+ }
1106
+ friend iterator operator+(difference_type d, iterator it) {
1107
+ it += d;
1108
+ return it;
1109
+ }
1110
+ iterator& operator-=(difference_type d) {
1111
+ it_ -= d;
1112
+ return *this;
1113
+ }
1114
+ friend iterator operator-(iterator it, difference_type d) {
1115
+ it -= d;
1116
+ return it;
1117
+ }
1118
+
1119
+ // indexable
1120
+ reference operator[](difference_type d) const { return *(*this + d); }
1121
+
1122
+ // random access iterator
1123
+ difference_type operator-(const iterator& x) const { return it_ - x.it_; }
1124
+
1125
+ private:
1126
+ template<typename OtherElement>
1127
+ friend class RepeatedPtrIterator;
1128
+
1129
+ // The internal iterator.
1130
+ void** it_;
1131
+ };
1132
+
1133
+
1134
+ } // namespace internal
1135
+
1136
+ template <typename Element>
1137
+ inline typename RepeatedPtrField<Element>::iterator
1138
+ RepeatedPtrField<Element>::begin() {
1139
+ return iterator(raw_data());
1140
+ }
1141
+ template <typename Element>
1142
+ inline typename RepeatedPtrField<Element>::const_iterator
1143
+ RepeatedPtrField<Element>::begin() const {
1144
+ return iterator(raw_data());
1145
+ }
1146
+ template <typename Element>
1147
+ inline typename RepeatedPtrField<Element>::iterator
1148
+ RepeatedPtrField<Element>::end() {
1149
+ return iterator(raw_data() + size());
1150
+ }
1151
+ template <typename Element>
1152
+ inline typename RepeatedPtrField<Element>::const_iterator
1153
+ RepeatedPtrField<Element>::end() const {
1154
+ return iterator(raw_data() + size());
1155
+ }
1156
+
1157
+ template <typename Element>
1158
+ inline typename RepeatedPtrField<Element>::pointer_iterator
1159
+ RepeatedPtrField<Element>::pointer_begin() {
1160
+ return pointer_iterator(raw_mutable_data());
1161
+ }
1162
+ template <typename Element>
1163
+ inline typename RepeatedPtrField<Element>::pointer_iterator
1164
+ RepeatedPtrField<Element>::pointer_end() {
1165
+ return pointer_iterator(raw_mutable_data() + size());
1166
+ }
1167
+
1168
+
1169
+ // Iterators and helper functions that follow the spirit of the STL
1170
+ // std::back_insert_iterator and std::back_inserter but are tailor-made
1171
+ // for RepeatedField and RepatedPtrField. Typical usage would be:
1172
+ //
1173
+ // std::copy(some_sequence.begin(), some_sequence.end(),
1174
+ // google::protobuf::RepeatedFieldBackInserter(proto.mutable_sequence()));
1175
+ //
1176
+ // Ported by johannes from util/gtl/proto-array-iterators-inl.h
1177
+
1178
+ namespace internal {
1179
+ // A back inserter for RepeatedField objects.
1180
+ template<typename T> class RepeatedFieldBackInsertIterator
1181
+ : public std::iterator<std::output_iterator_tag, T> {
1182
+ public:
1183
+ explicit RepeatedFieldBackInsertIterator(
1184
+ RepeatedField<T>* const mutable_field)
1185
+ : field_(mutable_field) {
1186
+ }
1187
+ RepeatedFieldBackInsertIterator<T>& operator=(const T& value) {
1188
+ field_->Add(value);
1189
+ return *this;
1190
+ }
1191
+ RepeatedFieldBackInsertIterator<T>& operator*() {
1192
+ return *this;
1193
+ }
1194
+ RepeatedFieldBackInsertIterator<T>& operator++() {
1195
+ return *this;
1196
+ }
1197
+ RepeatedFieldBackInsertIterator<T>& operator++(int ignores_parameter) {
1198
+ return *this;
1199
+ }
1200
+
1201
+ private:
1202
+ RepeatedField<T>* field_;
1203
+ };
1204
+
1205
+ // A back inserter for RepeatedPtrField objects.
1206
+ template<typename T> class RepeatedPtrFieldBackInsertIterator
1207
+ : public std::iterator<std::output_iterator_tag, T> {
1208
+ public:
1209
+ RepeatedPtrFieldBackInsertIterator(
1210
+ RepeatedPtrField<T>* const mutable_field)
1211
+ : field_(mutable_field) {
1212
+ }
1213
+ RepeatedPtrFieldBackInsertIterator<T>& operator=(const T& value) {
1214
+ *field_->Add() = value;
1215
+ return *this;
1216
+ }
1217
+ RepeatedPtrFieldBackInsertIterator<T>& operator=(
1218
+ const T* const ptr_to_value) {
1219
+ *field_->Add() = *ptr_to_value;
1220
+ return *this;
1221
+ }
1222
+ RepeatedPtrFieldBackInsertIterator<T>& operator*() {
1223
+ return *this;
1224
+ }
1225
+ RepeatedPtrFieldBackInsertIterator<T>& operator++() {
1226
+ return *this;
1227
+ }
1228
+ RepeatedPtrFieldBackInsertIterator<T>& operator++(int ignores_parameter) {
1229
+ return *this;
1230
+ }
1231
+
1232
+ private:
1233
+ RepeatedPtrField<T>* field_;
1234
+ };
1235
+
1236
+ // A back inserter for RepeatedPtrFields that inserts by transfering ownership
1237
+ // of a pointer.
1238
+ template<typename T> class AllocatedRepeatedPtrFieldBackInsertIterator
1239
+ : public std::iterator<std::output_iterator_tag, T> {
1240
+ public:
1241
+ explicit AllocatedRepeatedPtrFieldBackInsertIterator(
1242
+ RepeatedPtrField<T>* const mutable_field)
1243
+ : field_(mutable_field) {
1244
+ }
1245
+ AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator=(
1246
+ T* const ptr_to_value) {
1247
+ field_->AddAllocated(ptr_to_value);
1248
+ return *this;
1249
+ }
1250
+ AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator*() {
1251
+ return *this;
1252
+ }
1253
+ AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++() {
1254
+ return *this;
1255
+ }
1256
+ AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++(
1257
+ int ignores_parameter) {
1258
+ return *this;
1259
+ }
1260
+
1261
+ private:
1262
+ RepeatedPtrField<T>* field_;
1263
+ };
1264
+ } // namespace internal
1265
+
1266
+ // Provides a back insert iterator for RepeatedField instances,
1267
+ // similar to std::back_inserter(). Note the identically named
1268
+ // function for RepeatedPtrField instances.
1269
+ template<typename T> internal::RepeatedFieldBackInsertIterator<T>
1270
+ RepeatedFieldBackInserter(RepeatedField<T>* const mutable_field) {
1271
+ return internal::RepeatedFieldBackInsertIterator<T>(mutable_field);
1272
+ }
1273
+
1274
+ // Provides a back insert iterator for RepeatedPtrField instances,
1275
+ // similar to std::back_inserter(). Note the identically named
1276
+ // function for RepeatedField instances.
1277
+ template<typename T> internal::RepeatedPtrFieldBackInsertIterator<T>
1278
+ RepeatedFieldBackInserter(RepeatedPtrField<T>* const mutable_field) {
1279
+ return internal::RepeatedPtrFieldBackInsertIterator<T>(mutable_field);
1280
+ }
1281
+
1282
+ // Provides a back insert iterator for RepeatedPtrField instances
1283
+ // similar to std::back_inserter() which transfers the ownership while
1284
+ // copying elements.
1285
+ template<typename T> internal::AllocatedRepeatedPtrFieldBackInsertIterator<T>
1286
+ AllocatedRepeatedPtrFieldBackInserter(
1287
+ RepeatedPtrField<T>* const mutable_field) {
1288
+ return internal::AllocatedRepeatedPtrFieldBackInsertIterator<T>(
1289
+ mutable_field);
1290
+ }
1291
+
1292
+ } // namespace protobuf
1293
+
1294
+ } // namespace google
1295
+ #endif // GOOGLE_PROTOBUF_REPEATED_FIELD_H__