1 /* 2 * Copyright (c) Facebook, Inc. and its affiliates. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <memory> 20 #include <utility> 21 22 #include <folly/Overload.h> 23 #include <thrift/lib/cpp2/Thrift.h> 24 25 namespace apache { 26 namespace thrift { 27 28 // IndirectionWrapper 29 // 30 // Owns a value of type T, which may be incomplete at instantiation time. 31 // 32 // Provides access to the T and works with cpp.indirection. 33 // 34 // Expected to be used as a base class. Enforced by marking the dtor protected. 35 template <typename Derived, typename T> 36 class IndirectionWrapper { 37 private: 38 std::unique_ptr<T> raw_{new T()}; 39 40 protected: 41 ~IndirectionWrapper() = default; 42 43 public: 44 FBTHRIFT_CPP_DEFINE_MEMBER_INDIRECTION_FN(__fbthrift_data()); 45 46 IndirectionWrapper() = default; 47 IndirectionWrapper(const IndirectionWrapper & other)48 IndirectionWrapper(const IndirectionWrapper& other) 49 : raw_(new T(other.__fbthrift_data())) {} 50 noexcept(false)51 IndirectionWrapper(IndirectionWrapper&& other) noexcept(false) 52 : raw_(new T(std::move(other.__fbthrift_data()))) {} 53 noexcept(std::is_nothrow_copy_assignable_v<T>)54 IndirectionWrapper& operator=(const IndirectionWrapper& other) noexcept( 55 std::is_nothrow_copy_assignable_v<T>) { 56 __fbthrift_data() = other.__fbthrift_data(); 57 return *this; 58 } 59 noexcept(std::is_nothrow_move_assignable_v<T>)60 IndirectionWrapper& operator=(IndirectionWrapper&& other) noexcept( 61 std::is_nothrow_move_assignable_v<T>) { 62 __fbthrift_data() = std::move(other.__fbthrift_data()); 63 return *this; 64 } 65 66 friend bool operator==(const Derived& lhs, const Derived& rhs) { 67 return lhs.__fbthrift_data() == rhs.__fbthrift_data(); 68 } 69 70 friend bool operator<(const Derived& lhs, const Derived& rhs) { 71 return lhs.__fbthrift_data() < rhs.__fbthrift_data(); 72 } 73 __fbthrift_data()74 T& __fbthrift_data() & { return *raw_; } 75 __fbthrift_data()76 const T& __fbthrift_data() const& { return *raw_; } 77 __fbthrift_data()78 T&& __fbthrift_data() && { return std::move(*raw_); } 79 __fbthrift_data()80 const T&& __fbthrift_data() const&& { return std::move(*raw_); } 81 82 private: 83 friend struct apache::thrift::detail::st::struct_private_access; 84 __fbthrift_clear()85 void __fbthrift_clear() { apache::thrift::clear(__fbthrift_data()); } 86 }; 87 } // namespace thrift 88 } // namespace apache 89