protobuf/src/google/protobuf/stubs/casts.h
Go to the documentation of this file.
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2014 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 #ifndef GOOGLE_PROTOBUF_CASTS_H__
32 #define GOOGLE_PROTOBUF_CASTS_H__
33 
34 #include <google/protobuf/stubs/common.h>
35 
36 #include <google/protobuf/port_def.inc>
37 #include <type_traits>
38 
39 namespace google {
40 namespace protobuf {
41 namespace internal {
42 
43 // Use implicit_cast as a safe version of static_cast or const_cast
44 // for upcasting in the type hierarchy (i.e. casting a pointer to Foo
45 // to a pointer to SuperclassOfFoo or casting a pointer to Foo to
46 // a const pointer to Foo).
47 // When you use implicit_cast, the compiler checks that the cast is safe.
48 // Such explicit implicit_casts are necessary in surprisingly many
49 // situations where C++ demands an exact type match instead of an
50 // argument type convertible to a target type.
51 //
52 // The From type can be inferred, so the preferred syntax for using
53 // implicit_cast is the same as for static_cast etc.:
54 //
55 // implicit_cast<ToType>(expr)
56 //
57 // implicit_cast would have been part of the C++ standard library,
58 // but the proposal was submitted too late. It will probably make
59 // its way into the language in the future.
60 template<typename To, typename From>
61 inline To implicit_cast(From const &f) {
62  return f;
63 }
64 
65 // When you upcast (that is, cast a pointer from type Foo to type
66 // SuperclassOfFoo), it's fine to use implicit_cast<>, since upcasts
67 // always succeed. When you downcast (that is, cast a pointer from
68 // type Foo to type SubclassOfFoo), static_cast<> isn't safe, because
69 // how do you know the pointer is really of type SubclassOfFoo? It
70 // could be a bare Foo, or of type DifferentSubclassOfFoo. Thus,
71 // when you downcast, you should use this macro. In debug mode, we
72 // use dynamic_cast<> to double-check the downcast is legal (we die
73 // if it's not). In normal mode, we do the efficient static_cast<>
74 // instead. Thus, it's important to test in debug mode to make sure
75 // the cast is legal!
76 // This is the only place in the code we should use dynamic_cast<>.
77 // In particular, you SHOULDN'T be using dynamic_cast<> in order to
78 // do RTTI (eg code like this:
79 // if (dynamic_cast<Subclass1>(foo)) HandleASubclass1Object(foo);
80 // if (dynamic_cast<Subclass2>(foo)) HandleASubclass2Object(foo);
81 // You should design the code some other way not to need this.
82 
83 template<typename To, typename From> // use like this: down_cast<T*>(foo);
84 inline To down_cast(From* f) { // so we only accept pointers
85  // Ensures that To is a sub-type of From *. This test is here only
86  // for compile-time type checking, and has no overhead in an
87  // optimized build at run-time, as it will be optimized away
88  // completely.
89  if (false) {
90  implicit_cast<From*, To>(0);
91  }
92 
93 #if !defined(NDEBUG) && PROTOBUF_RTTI
94  assert(f == nullptr || dynamic_cast<To>(f) != nullptr); // RTTI: debug mode only!
95 #endif
96  return static_cast<To>(f);
97 }
98 
99 template<typename To, typename From> // use like this: down_cast<T&>(foo);
100 inline To down_cast(From& f) {
101  typedef typename std::remove_reference<To>::type* ToAsPointer;
102  // Ensures that To is a sub-type of From *. This test is here only
103  // for compile-time type checking, and has no overhead in an
104  // optimized build at run-time, as it will be optimized away
105  // completely.
106  if (false) {
107  implicit_cast<From*, ToAsPointer>(0);
108  }
109 
110 #if !defined(NDEBUG) && PROTOBUF_RTTI
111  // RTTI: debug mode only!
112  assert(dynamic_cast<ToAsPointer>(&f) != nullptr);
113 #endif
114  return *static_cast<ToAsPointer>(&f);
115 }
116 
117 template<typename To, typename From>
118 inline To bit_cast(const From& from) {
119  static_assert(sizeof(From) == sizeof(To), "bit_cast_with_different_sizes");
120  To dest;
121  memcpy(&dest, &from, sizeof(dest));
122  return dest;
123 }
124 
125 } // namespace internal
126 
127 // We made these internal so that they would show up as such in the docs,
128 // but we don't want to stick "internal::" in front of them everywhere.
130 using internal::down_cast;
131 using internal::bit_cast;
132 
133 } // namespace protobuf
134 } // namespace google
135 
136 #include <google/protobuf/port_undef.inc>
137 
138 #endif // GOOGLE_PROTOBUF_CASTS_H__
google::protobuf.internal::bit_cast
To bit_cast(const From &from)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/casts.h:116
google::protobuf
Definition: bloaty/third_party/protobuf/benchmarks/util/data_proto2_to_proto3_util.h:12
from
size_t from
Definition: abseil-cpp/absl/container/internal/layout_test.cc:1384
memcpy
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
autogen_x86imm.f
f
Definition: autogen_x86imm.py:9
google::protobuf.internal::down_cast
To down_cast(From *f)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/casts.h:82
tests.qps.qps_worker.dest
dest
Definition: qps_worker.py:45
google::protobuf.internal::implicit_cast
To implicit_cast(From const &f)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/casts.h:59
internal
Definition: benchmark/test/output_test_helper.cc:20
asyncio_get_stats.type
type
Definition: asyncio_get_stats.py:37
google
Definition: bloaty/third_party/protobuf/benchmarks/util/data_proto2_to_proto3_util.h:11


grpc
Author(s):
autogenerated on Fri May 16 2025 02:57:52