GRPC C++  1.66.0
slice_cast.h
Go to the documentation of this file.
1 // Copyright 2022 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef GRPC_EVENT_ENGINE_INTERNAL_SLICE_CAST_H
16 #define GRPC_EVENT_ENGINE_INTERNAL_SLICE_CAST_H
17 
18 namespace grpc_event_engine {
19 namespace experimental {
20 namespace internal {
21 
22 // Opt-in trait class for slice conversions.
23 // Declare a specialization of this class for any types that are compatible
24 // with `SliceCast`. Both ways need to be declared (i.e. if
25 // SliceCastable<A,B> exists, you should declare
26 // SliceCastable<B,A> too).
27 // The type has no members, it's just the existance of the specialization that
28 // unlocks SliceCast usage for a type pair.
29 template <typename Result, typename T>
31 
32 // This is strictly too wide, but consider all types to be SliceCast-able to
33 // themselves.
34 // Unfortunately this allows `const int& x = SliceCast<int>(x);` which is kind
35 // of bogus.
36 template <typename A>
37 struct SliceCastable<A, A> {};
38 
39 // Cast to `const Result&` from `const T&` without any runtime checks.
40 // This is only valid if `sizeof(Result) == sizeof(T)`, and if `Result`, `T` are
41 // opted in as compatible via `SliceCastable`.
42 template <typename Result, typename T>
43 const Result& SliceCast(const T& value, SliceCastable<Result, T> = {}) {
44  // Insist upon sizes being equal to catch mismatches.
45  // We assume if sizes are opted in and sizes are equal then yes, these two
46  // types are expected to be layout compatible and actually appear to be.
47  static_assert(sizeof(Result) == sizeof(T), "size mismatch");
48  return reinterpret_cast<const Result&>(value);
49 }
50 
51 // Cast to `Result&` from `T&` without any runtime checks.
52 // This is only valid if `sizeof(Result) == sizeof(T)`, and if `Result`, `T` are
53 // opted in as compatible via `SliceCastable`.
54 template <typename Result, typename T>
55 Result& SliceCast(T& value, SliceCastable<Result, T> = {}) {
56  // Insist upon sizes being equal to catch mismatches.
57  // We assume if sizes are opted in and sizes are equal then yes, these two
58  // types are expected to be layout compatible and actually appear to be.
59  static_assert(sizeof(Result) == sizeof(T), "size mismatch");
60  return reinterpret_cast<Result&>(value);
61 }
62 
63 // Cast to `Result&&` from `T&&` without any runtime checks.
64 // This is only valid if `sizeof(Result) == sizeof(T)`, and if `Result`, `T` are
65 // opted in as compatible via `SliceCastable`.
66 template <typename Result, typename T>
67 Result&& SliceCast(T&& value, SliceCastable<Result, T> = {}) {
68  // Insist upon sizes being equal to catch mismatches.
69  // We assume if sizes are opted in and sizes are equal then yes, these two
70  // types are expected to be layout compatible and actually appear to be.
71  static_assert(sizeof(Result) == sizeof(T), "size mismatch");
72  return reinterpret_cast<Result&&>(value);
73 }
74 
75 } // namespace internal
76 } // namespace experimental
77 } // namespace grpc_event_engine
78 
79 #endif // GRPC_EVENT_ENGINE_INTERNAL_SLICE_CAST_H
grpc_event_engine::experimental::internal::SliceCastable
Definition: slice_cast.h:30
grpc_event_engine
Definition: endpoint_config.h:24
grpc_event_engine::experimental::internal::SliceCast
const Result & SliceCast(const T &value, SliceCastable< Result, T >={})
Definition: slice_cast.h:43