LCOV - code coverage report
Current view: top level - third_party/protobuf/src/google/protobuf - reflection.h (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 0 7 0.0 %
Date: 2015-10-10 Functions: 0 2 0.0 %

          Line data    Source code
       1             : // Protocol Buffers - Google's data interchange format
       2             : // Copyright 2008 Google Inc.  All rights reserved.
       3             : // https://developers.google.com/protocol-buffers/
       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             : // This header defines the RepeatedFieldRef class template used to access
      32             : // repeated fields with protobuf reflection API.
      33             : #ifndef GOOGLE_PROTOBUF_REFLECTION_H__
      34             : #define GOOGLE_PROTOBUF_REFLECTION_H__
      35             : 
      36             : #include <memory>
      37             : #ifndef _SHARED_PTR_H
      38             : #include <google/protobuf/stubs/shared_ptr.h>
      39             : #endif
      40             : 
      41             : #include <google/protobuf/message.h>
      42             : #include <google/protobuf/generated_enum_util.h>
      43             : 
      44             : namespace google {
      45             : namespace protobuf {
      46             : namespace internal {
      47             : template<typename T, typename Enable = void>
      48             : struct RefTypeTraits;
      49             : }  // namespace internal
      50             : 
      51             : template<typename T>
      52             : RepeatedFieldRef<T> Reflection::GetRepeatedFieldRef(
      53             :     const Message& message, const FieldDescriptor* field) const {
      54             :   return RepeatedFieldRef<T>(message, field);
      55             : }
      56             : 
      57             : template<typename T>
      58             : MutableRepeatedFieldRef<T> Reflection::GetMutableRepeatedFieldRef(
      59             :     Message* message, const FieldDescriptor* field) const {
      60             :   return MutableRepeatedFieldRef<T>(message, field);
      61             : }
      62             : 
      63             : // RepeatedFieldRef definition for non-message types.
      64             : template<typename T>
      65             : class RepeatedFieldRef<
      66             :     T, typename internal::enable_if<!internal::is_base_of<Message, T>::value>::type> {
      67             :   typedef typename internal::RefTypeTraits<T>::iterator IteratorType;
      68             :   typedef typename internal::RefTypeTraits<T>::AccessorType AccessorType;
      69             : 
      70             :  public:
      71             :   bool empty() const {
      72             :     return accessor_->IsEmpty(data_);
      73             :   }
      74             :   int size() const {
      75             :     return accessor_->Size(data_);
      76             :   }
      77             :   T Get(int index) const {
      78             :     return accessor_->template Get<T>(data_, index);
      79             :   }
      80             : 
      81             :   typedef IteratorType iterator;
      82             :   typedef IteratorType const_iterator;
      83             :   iterator begin() const {
      84             :     return iterator(data_, accessor_, true);
      85             :   }
      86             :   iterator end() const {
      87             :     return iterator(data_, accessor_, false);
      88             :   }
      89             : 
      90             :  private:
      91             :   friend class Reflection;
      92             :   RepeatedFieldRef(
      93             :       const Message& message,
      94             :       const FieldDescriptor* field) {
      95             :     const Reflection* reflection = message.GetReflection();
      96             :     data_ = reflection->RepeatedFieldData(
      97             :         const_cast<Message*>(&message), field,
      98             :         internal::RefTypeTraits<T>::cpp_type, NULL);
      99             :     accessor_ = reflection->RepeatedFieldAccessor(field);
     100             :   }
     101             : 
     102             :   const void* data_;
     103             :   const AccessorType* accessor_;
     104             : };
     105             : 
     106             : // MutableRepeatedFieldRef definition for non-message types.
     107             : template<typename T>
     108             : class MutableRepeatedFieldRef<
     109             :     T, typename internal::enable_if<!internal::is_base_of<Message, T>::value>::type> {
     110             :   typedef typename internal::RefTypeTraits<T>::AccessorType AccessorType;
     111             : 
     112             :  public:
     113             :   bool empty() const {
     114             :     return accessor_->IsEmpty(data_);
     115             :   }
     116             :   int size() const {
     117             :     return accessor_->Size(data_);
     118             :   }
     119             :   T Get(int index) const {
     120             :     return accessor_->template Get<T>(data_, index);
     121             :   }
     122             : 
     123             :   void Set(int index, const T& value) const {
     124             :     accessor_->template Set<T>(data_, index, value);
     125             :   }
     126             :   void Add(const T& value) const {
     127             :     accessor_->template Add<T>(data_, value);
     128             :   }
     129             :   void RemoveLast() const {
     130             :     accessor_->RemoveLast(data_);
     131             :   }
     132             :   void SwapElements(int index1, int index2) const {
     133             :     accessor_->SwapElements(data_, index1, index2);
     134             :   }
     135             :   void Clear() const {
     136             :     accessor_->Clear(data_);
     137             :   }
     138             : 
     139             :   void Swap(const MutableRepeatedFieldRef& other) const {
     140             :     accessor_->Swap(data_, other.accessor_, other.data_);
     141             :   }
     142             : 
     143             :   template<typename Container>
     144             :   void MergeFrom(const Container& container) const {
     145             :     typedef typename Container::const_iterator Iterator;
     146             :     for (Iterator it = container.begin(); it != container.end(); ++it) {
     147             :       Add(*it);
     148             :     }
     149             :   }
     150             :   template<typename Container>
     151             :   void CopyFrom(const Container& container) const {
     152             :     Clear();
     153             :     MergeFrom(container);
     154             :   }
     155             : 
     156             :  private:
     157             :   friend class Reflection;
     158             :   MutableRepeatedFieldRef(
     159             :       Message* message,
     160             :       const FieldDescriptor* field) {
     161             :     const Reflection* reflection = message->GetReflection();
     162             :     data_ = reflection->RepeatedFieldData(
     163             :         message, field, internal::RefTypeTraits<T>::cpp_type, NULL);
     164             :     accessor_ = reflection->RepeatedFieldAccessor(field);
     165             :   }
     166             : 
     167             :   void* data_;
     168             :   const AccessorType* accessor_;
     169             : };
     170             : 
     171             : // RepeatedFieldRef definition for message types.
     172             : template<typename T>
     173             : class RepeatedFieldRef<
     174             :     T, typename internal::enable_if<internal::is_base_of<Message, T>::value>::type> {
     175             :   typedef typename internal::RefTypeTraits<T>::iterator IteratorType;
     176             :   typedef typename internal::RefTypeTraits<T>::AccessorType AccessorType;
     177             : 
     178             :  public:
     179             :   bool empty() const {
     180             :     return accessor_->IsEmpty(data_);
     181             :   }
     182             :   int size() const {
     183             :     return accessor_->Size(data_);
     184             :   }
     185             :   // This method returns a reference to the underlying message object if it
     186             :   // exists. If a message object doesn't exist (e.g., data stored in serialized
     187             :   // form), scratch_space will be filled with the data and a reference to it
     188             :   // will be returned.
     189             :   //
     190             :   // Example:
     191             :   //   RepeatedFieldRef<Message> h = ...
     192             :   //   unique_ptr<Message> scratch_space(h.NewMessage());
     193             :   //   const Message& item = h.Get(index, scratch_space.get());
     194             :   const T& Get(int index, T* scratch_space) const {
     195             :     return *static_cast<const T*>(accessor_->Get(data_, index, scratch_space));
     196             :   }
     197             :   // Create a new message of the same type as the messages stored in this
     198             :   // repeated field. Caller takes ownership of the returned object.
     199             :   T* NewMessage() const {
     200             :     return static_cast<T*>(default_instance_->New());
     201             :   }
     202             : 
     203             :   typedef IteratorType iterator;
     204             :   typedef IteratorType const_iterator;
     205             :   iterator begin() const {
     206             :     return iterator(data_, accessor_, true, NewMessage());
     207             :   }
     208             :   iterator end() const {
     209             :     return iterator(data_, accessor_, false, NewMessage());
     210             :   }
     211             : 
     212             :  private:
     213             :   friend class Reflection;
     214             :   RepeatedFieldRef(
     215             :       const Message& message,
     216             :       const FieldDescriptor* field) {
     217             :     const Reflection* reflection = message.GetReflection();
     218             :     data_ = reflection->RepeatedFieldData(
     219             :         const_cast<Message*>(&message), field,
     220             :         internal::RefTypeTraits<T>::cpp_type,
     221             :         internal::RefTypeTraits<T>::GetMessageFieldDescriptor());
     222             :     accessor_ = reflection->RepeatedFieldAccessor(field);
     223             :     default_instance_ =
     224             :         reflection->GetMessageFactory()->GetPrototype(field->message_type());
     225             :   }
     226             : 
     227             :   const void* data_;
     228             :   const AccessorType* accessor_;
     229             :   const Message* default_instance_;
     230             : };
     231             : 
     232             : // MutableRepeatedFieldRef definition for message types.
     233             : template<typename T>
     234             : class MutableRepeatedFieldRef<
     235             :     T, typename internal::enable_if<internal::is_base_of<Message, T>::value>::type> {
     236             :   typedef typename internal::RefTypeTraits<T>::AccessorType AccessorType;
     237             : 
     238             :  public:
     239             :   bool empty() const {
     240             :     return accessor_->IsEmpty(data_);
     241             :   }
     242             :   int size() const {
     243             :     return accessor_->Size(data_);
     244             :   }
     245             :   // See comments for RepeatedFieldRef<Message>::Get()
     246             :   const T& Get(int index, T* scratch_space) const {
     247             :     return *static_cast<const T*>(accessor_->Get(data_, index, scratch_space));
     248             :   }
     249             :   // Create a new message of the same type as the messages stored in this
     250             :   // repeated field. Caller takes ownership of the returned object.
     251             :   T* NewMessage() const {
     252             :     return static_cast<T*>(default_instance_->New());
     253             :   }
     254             : 
     255             :   void Set(int index, const T& value) const {
     256             :     accessor_->Set(data_, index, &value);
     257             :   }
     258             :   void Add(const T& value) const {
     259             :     accessor_->Add(data_, &value);
     260             :   }
     261             :   void RemoveLast() const {
     262             :     accessor_->RemoveLast(data_);
     263             :   }
     264             :   void SwapElements(int index1, int index2) const {
     265             :     accessor_->SwapElements(data_, index1, index2);
     266             :   }
     267             :   void Clear() const {
     268             :     accessor_->Clear(data_);
     269             :   }
     270             : 
     271             :   void Swap(const MutableRepeatedFieldRef& other) const {
     272             :     accessor_->Swap(data_, other.accessor_, other.data_);
     273             :   }
     274             : 
     275             :   template<typename Container>
     276             :   void MergeFrom(const Container& container) const {
     277             :     typedef typename Container::const_iterator Iterator;
     278             :     for (Iterator it = container.begin(); it != container.end(); ++it) {
     279             :       Add(*it);
     280             :     }
     281             :   }
     282             :   template<typename Container>
     283             :   void CopyFrom(const Container& container) const {
     284             :     Clear();
     285             :     MergeFrom(container);
     286             :   }
     287             : 
     288             :  private:
     289             :   friend class Reflection;
     290             :   MutableRepeatedFieldRef(
     291             :       Message* message,
     292             :       const FieldDescriptor* field) {
     293             :     const Reflection* reflection = message->GetReflection();
     294             :     data_ = reflection->RepeatedFieldData(
     295             :         message, field, internal::RefTypeTraits<T>::cpp_type,
     296             :         internal::RefTypeTraits<T>::GetMessageFieldDescriptor());
     297             :     accessor_ = reflection->RepeatedFieldAccessor(field);
     298             :     default_instance_ =
     299             :         reflection->GetMessageFactory()->GetPrototype(field->message_type());
     300             :   }
     301             : 
     302             :   void* data_;
     303             :   const AccessorType* accessor_;
     304             :   const Message* default_instance_;
     305             : };
     306             : 
     307             : namespace internal {
     308             : // Interfaces used to implement reflection RepeatedFieldRef API.
     309             : // Reflection::GetRepeatedAccessor() should return a pointer to an singleton
     310             : // object that implements the below interface.
     311             : //
     312             : // This interface passes/returns values using void pointers. The actual type
     313             : // of the value depends on the field's cpp_type. Following is a mapping from
     314             : // cpp_type to the type that should be used in this interface:
     315             : //
     316             : //   field->cpp_type()      T                Actual type of void*
     317             : //   CPPTYPE_INT32        int32                   int32
     318             : //   CPPTYPE_UINT32       uint32                  uint32
     319             : //   CPPTYPE_INT64        int64                   int64
     320             : //   CPPTYPE_UINT64       uint64                  uint64
     321             : //   CPPTYPE_DOUBLE       double                  double
     322             : //   CPPTYPE_FLOAT        float                   float
     323             : //   CPPTYPE_BOOL         bool                    bool
     324             : //   CPPTYPE_ENUM         generated enum type     int32
     325             : //   CPPTYPE_STRING       string                  string
     326             : //   CPPTYPE_MESSAGE      generated message type  google::protobuf::Message
     327             : //                        or google::protobuf::Message
     328             : //
     329             : // Note that for enums we use int32 in the interface.
     330             : //
     331             : // You can map from T to the actual type using RefTypeTraits:
     332             : //   typedef RefTypeTraits<T>::AccessorValueType ActualType;
     333           0 : class LIBPROTOBUF_EXPORT RepeatedFieldAccessor {
     334             :  public:
     335             :   // Typedefs for clarity.
     336             :   typedef void Field;
     337             :   typedef void Value;
     338             :   typedef void Iterator;
     339             : 
     340             :   virtual ~RepeatedFieldAccessor();
     341             :   virtual bool IsEmpty(const Field* data) const = 0;
     342             :   virtual int Size(const Field* data) const = 0;
     343             :   // Depends on the underlying representation of the repeated field, this
     344             :   // method can return a pointer to the underlying object if such an object
     345             :   // exists, or fill the data into scratch_space and return scratch_space.
     346             :   // Callers of this method must ensure scratch_space is a valid pointer
     347             :   // to a mutable object of the correct type.
     348             :   virtual const Value* Get(
     349             :       const Field* data, int index, Value* scratch_space) const = 0;
     350             : 
     351             :   virtual void Clear(Field* data) const = 0;
     352             :   virtual void Set(Field* data, int index, const Value* value) const = 0;
     353             :   virtual void Add(Field* data, const Value* value) const = 0;
     354             :   virtual void RemoveLast(Field* data) const = 0;
     355             :   virtual void SwapElements(Field* data, int index1, int index2) const = 0;
     356             :   virtual void Swap(Field* data, const RepeatedFieldAccessor* other_mutator,
     357             :                     Field* other_data) const = 0;
     358             : 
     359             :   // Create an iterator that points at the begining of the repeated field.
     360             :   virtual Iterator* BeginIterator(const Field* data) const = 0;
     361             :   // Create an iterator that points at the end of the repeated field.
     362             :   virtual Iterator* EndIterator(const Field* data) const = 0;
     363             :   // Make a copy of an iterator and return the new copy.
     364             :   virtual Iterator* CopyIterator(const Field* data,
     365             :                                  const Iterator* iterator) const = 0;
     366             :   // Move an iterator to point to the next element.
     367             :   virtual Iterator* AdvanceIterator(const Field* data,
     368             :                                     Iterator* iterator) const = 0;
     369             :   // Compare whether two iterators point to the same element.
     370             :   virtual bool EqualsIterator(const Field* data, const Iterator* a,
     371             :                               const Iterator* b) const = 0;
     372             :   // Delete an iterator created by BeginIterator(), EndIterator() and
     373             :   // CopyIterator().
     374             :   virtual void DeleteIterator(const Field* data, Iterator* iterator) const = 0;
     375             :   // Like Get() but for iterators.
     376             :   virtual const Value* GetIteratorValue(const Field* data,
     377             :                                         const Iterator* iterator,
     378             :                                         Value* scratch_space) const = 0;
     379             : 
     380             :   // Templated methods that make using this interface easier for non-message
     381             :   // types.
     382             :   template<typename T>
     383           0 :   T Get(const Field* data, int index) const {
     384             :     typedef typename RefTypeTraits<T>::AccessorValueType ActualType;
     385             :     ActualType scratch_space;
     386             :     return static_cast<T>(
     387             :         *reinterpret_cast<const ActualType*>(
     388           0 :             Get(data, index, static_cast<Value*>(&scratch_space))));
     389             :   }
     390             : 
     391             :   template<typename T, typename ValueType>
     392             :   void Set(Field* data, int index, const ValueType& value) const {
     393             :     typedef typename RefTypeTraits<T>::AccessorValueType ActualType;
     394             :     // In this RepeatedFieldAccessor interface we pass/return data using
     395             :     // raw pointers. Type of the data these raw pointers point to should
     396             :     // be ActualType. Here we have a ValueType object and want a ActualType
     397             :     // pointer. We can't cast a ValueType pointer to an ActualType pointer
     398             :     // directly because their type might be different (for enums ValueType
     399             :     // may be a generated enum type while ActualType is int32). To be safe
     400             :     // we make a copy to get a temporary ActualType object and use it.
     401             :     ActualType tmp = static_cast<ActualType>(value);
     402             :     Set(data, index, static_cast<const Value*>(&tmp));
     403             :   }
     404             : 
     405             :   template<typename T, typename ValueType>
     406           0 :   void Add(Field* data, const ValueType& value) const {
     407             :     typedef typename RefTypeTraits<T>::AccessorValueType ActualType;
     408             :     // In this RepeatedFieldAccessor interface we pass/return data using
     409             :     // raw pointers. Type of the data these raw pointers point to should
     410             :     // be ActualType. Here we have a ValueType object and want a ActualType
     411             :     // pointer. We can't cast a ValueType pointer to an ActualType pointer
     412             :     // directly because their type might be different (for enums ValueType
     413             :     // may be a generated enum type while ActualType is int32). To be safe
     414             :     // we make a copy to get a temporary ActualType object and use it.
     415           0 :     ActualType tmp = static_cast<ActualType>(value);
     416           0 :     Add(data, static_cast<const Value*>(&tmp));
     417           0 :   }
     418             : };
     419             : 
     420             : // Implement (Mutable)RepeatedFieldRef::iterator
     421             : template<typename T>
     422             : class RepeatedFieldRefIterator
     423             :     : public std::iterator<std::forward_iterator_tag, T> {
     424             :   typedef typename RefTypeTraits<T>::AccessorValueType AccessorValueType;
     425             :   typedef typename RefTypeTraits<T>::IteratorValueType IteratorValueType;
     426             :   typedef typename RefTypeTraits<T>::IteratorPointerType IteratorPointerType;
     427             : 
     428             :  public:
     429             :   // Constructor for non-message fields.
     430             :   RepeatedFieldRefIterator(const void* data,
     431             :                            const RepeatedFieldAccessor* accessor,
     432             :                            bool begin)
     433             :       : data_(data), accessor_(accessor),
     434             :         iterator_(begin ? accessor->BeginIterator(data) :
     435             :                           accessor->EndIterator(data)),
     436             :         scratch_space_(new AccessorValueType) {
     437             :   }
     438             :   // Constructor for message fields.
     439             :   RepeatedFieldRefIterator(const void* data,
     440             :                            const RepeatedFieldAccessor* accessor,
     441             :                            bool begin,
     442             :                            AccessorValueType* scratch_space)
     443             :       : data_(data), accessor_(accessor),
     444             :         iterator_(begin ? accessor->BeginIterator(data) :
     445             :                           accessor->EndIterator(data)),
     446             :         scratch_space_(scratch_space) {
     447             :   }
     448             :   ~RepeatedFieldRefIterator() {
     449             :     accessor_->DeleteIterator(data_, iterator_);
     450             :   }
     451             :   RepeatedFieldRefIterator operator++(int) {
     452             :     RepeatedFieldRefIterator tmp(*this);
     453             :     iterator_ = accessor_->AdvanceIterator(data_, iterator_);
     454             :     return tmp;
     455             :   }
     456             :   RepeatedFieldRefIterator& operator++() {
     457             :     iterator_ = accessor_->AdvanceIterator(data_, iterator_);
     458             :     return *this;
     459             :   }
     460             :   IteratorValueType operator*() const {
     461             :     return static_cast<IteratorValueType>(
     462             :         *static_cast<const AccessorValueType*>(
     463             :             accessor_->GetIteratorValue(
     464             :                 data_, iterator_, scratch_space_.get())));
     465             :   }
     466             :   IteratorPointerType operator->() const {
     467             :     return static_cast<IteratorPointerType>(
     468             :         accessor_->GetIteratorValue(
     469             :             data_, iterator_, scratch_space_.get()));
     470             :   }
     471             :   bool operator!=(const RepeatedFieldRefIterator& other) const {
     472             :     assert(data_ == other.data_);
     473             :     assert(accessor_ == other.accessor_);
     474             :     return !accessor_->EqualsIterator(data_, iterator_, other.iterator_);
     475             :   }
     476             :   bool operator==(const RepeatedFieldRefIterator& other) const {
     477             :     return !this->operator!=(other);
     478             :   }
     479             : 
     480             :   RepeatedFieldRefIterator(const RepeatedFieldRefIterator& other)
     481             :       : data_(other.data_), accessor_(other.accessor_),
     482             :         iterator_(accessor_->CopyIterator(data_, other.iterator_)) {
     483             :   }
     484             :   RepeatedFieldRefIterator& operator=(const RepeatedFieldRefIterator& other) {
     485             :     if (this != &other) {
     486             :       accessor_->DeleteIterator(data_, iterator_);
     487             :       data_ = other.data_;
     488             :       accessor_ = other.accessor_;
     489             :       iterator_ = accessor_->CopyIterator(data_, other.iterator_);
     490             :     }
     491             :     return *this;
     492             :   }
     493             : 
     494             :  protected:
     495             :   const void* data_;
     496             :   const RepeatedFieldAccessor* accessor_;
     497             :   void* iterator_;
     498             :   google::protobuf::scoped_ptr<AccessorValueType> scratch_space_;
     499             : };
     500             : 
     501             : // TypeTraits that maps the type parameter T of RepeatedFieldRef or
     502             : // MutableRepeatedFieldRef to corresponding iterator type,
     503             : // RepeatedFieldAccessor type, etc.
     504             : template<typename T>
     505             : struct PrimitiveTraits {
     506             :   static const bool is_primitive = false;
     507             : };
     508             : #define DEFINE_PRIMITIVE(TYPE, type) \
     509             :     template<> struct PrimitiveTraits<type> { \
     510             :       static const bool is_primitive = true; \
     511             :       static const FieldDescriptor::CppType cpp_type = \
     512             :           FieldDescriptor::CPPTYPE_ ## TYPE; \
     513             :     };
     514             : DEFINE_PRIMITIVE(INT32, int32)
     515             : DEFINE_PRIMITIVE(UINT32, uint32)
     516             : DEFINE_PRIMITIVE(INT64, int64)
     517             : DEFINE_PRIMITIVE(UINT64, uint64)
     518             : DEFINE_PRIMITIVE(FLOAT, float)
     519             : DEFINE_PRIMITIVE(DOUBLE, double)
     520             : DEFINE_PRIMITIVE(BOOL, bool)
     521             : #undef DEFINE_PRIMITIVE
     522             : 
     523             : template<typename T>
     524             : struct RefTypeTraits<
     525             :     T, typename internal::enable_if<PrimitiveTraits<T>::is_primitive>::type> {
     526             :   typedef RepeatedFieldRefIterator<T> iterator;
     527             :   typedef RepeatedFieldAccessor AccessorType;
     528             :   typedef T AccessorValueType;
     529             :   typedef T IteratorValueType;
     530             :   typedef T* IteratorPointerType;
     531             :   static const FieldDescriptor::CppType cpp_type =
     532             :       PrimitiveTraits<T>::cpp_type;
     533             :   static const Descriptor* GetMessageFieldDescriptor() {
     534             :     return NULL;
     535             :   }
     536             : };
     537             : 
     538             : template<typename T>
     539             : struct RefTypeTraits<
     540             :     T, typename internal::enable_if<is_proto_enum<T>::value>::type> {
     541             :   typedef RepeatedFieldRefIterator<T> iterator;
     542             :   typedef RepeatedFieldAccessor AccessorType;
     543             :   // We use int32 for repeated enums in RepeatedFieldAccessor.
     544             :   typedef int32 AccessorValueType;
     545             :   typedef T IteratorValueType;
     546             :   typedef int32* IteratorPointerType;
     547             :   static const FieldDescriptor::CppType cpp_type =
     548             :       FieldDescriptor::CPPTYPE_ENUM;
     549             :   static const Descriptor* GetMessageFieldDescriptor() {
     550             :     return NULL;
     551             :   }
     552             : };
     553             : 
     554             : template<typename T>
     555             : struct RefTypeTraits<
     556             :     T, typename internal::enable_if< ::google::protobuf::internal::is_same<string, T>::value>::type> {
     557             :   typedef RepeatedFieldRefIterator<T> iterator;
     558             :   typedef RepeatedFieldAccessor AccessorType;
     559             :   typedef string AccessorValueType;
     560             :   typedef string IteratorValueType;
     561             :   typedef string* IteratorPointerType;
     562             :   static const FieldDescriptor::CppType cpp_type =
     563             :       FieldDescriptor::CPPTYPE_STRING;
     564             :   static const Descriptor* GetMessageFieldDescriptor() {
     565             :     return NULL;
     566             :   }
     567             : };
     568             : 
     569             : template<typename T>
     570             : struct MessageDescriptorGetter {
     571             :   static const Descriptor* get() {
     572             :     return T::default_instance().GetDescriptor();
     573             :   }
     574             : };
     575             : template<>
     576             : struct MessageDescriptorGetter<Message> {
     577             :   static const Descriptor* get() {
     578             :     return NULL;
     579             :   }
     580             : };
     581             : 
     582             : template<typename T>
     583             : struct RefTypeTraits<
     584             :     T, typename internal::enable_if<internal::is_base_of<Message, T>::value>::type> {
     585             :   typedef RepeatedFieldRefIterator<T> iterator;
     586             :   typedef RepeatedFieldAccessor AccessorType;
     587             :   typedef Message AccessorValueType;
     588             :   typedef const T& IteratorValueType;
     589             :   typedef const T* IteratorPointerType;
     590             :   static const FieldDescriptor::CppType cpp_type =
     591             :       FieldDescriptor::CPPTYPE_MESSAGE;
     592             :   static const Descriptor* GetMessageFieldDescriptor() {
     593             :     return MessageDescriptorGetter<T>::get();
     594             :   }
     595             : };
     596             : }  // namespace internal
     597             : }  // namespace protobuf
     598             : }  // namespace google
     599             : 
     600             : #endif  // GOOGLE_PROTOBUF_REFLECTION_H__

Generated by: LCOV version 1.10