LLVM: include/llvm/Support/ErrorOr.h Source File (original) (raw)

57 template friend class ErrorOr;

58

59 static constexpr bool isRef = std::is_reference_v;

60

61 using wrap = std::reference_wrapper<std::remove_reference_t>;

62

63public:

64 using storage_type = std::conditional_t<isRef, wrap, T>;

65

66private:

67 using reference = std::remove_reference_t &;

68 using const_reference = const std::remove_reference_t &;

69 using pointer = std::remove_reference_t *;

70 using const_pointer = const std::remove_reference_t *;

71

72public:

73 template

75 std::enable_if_t<std::is_error_code_enum::value ||

76 std::is_error_condition_enum::value,

77 void *> = nullptr)

78 : HasError(true) {

79 new (getErrorStorage()) std::error_code(make_error_code(ErrorCode));

80 }

81

83 new (getErrorStorage()) std::error_code(EC);

84 }

85

86 template

88 std::enable_if_t<std::is_convertible_v<OtherT, T>> * = nullptr)

89 : HasError(false) {

90 new (getStorage()) storage_type(std::forward(Val));

91 }

92

94 copyConstruct(Other);

95 }

96

97 template

99 std::enable_if_t<std::is_convertible_v<OtherT, T>> * = nullptr) {

100 copyConstruct(Other);

101 }

102

103 template

106 std::enable_if_t<!std::is_convertible_v<OtherT, const T &>> * = nullptr) {

107 copyConstruct(Other);

108 }

109

111 moveConstruct(std::move(Other));

112 }

113

114 template

116 std::enable_if_t<std::is_convertible_v<OtherT, T>> * = nullptr) {

117 moveConstruct(std::move(Other));

118 }

119

120

121

122 template

125 std::enable_if_t<!std::is_convertible_v<OtherT, T>> * = nullptr) {

126 moveConstruct(std::move(Other));

127 }

128

130 copyAssign(Other);

131 return *this;

132 }

133

135 moveAssign(std::move(Other));

136 return *this;

137 }

138

140 if (!HasError)

141 getStorage()->~storage_type();

142 }

143

144

145 explicit operator bool() const {

146 return !HasError;

147 }

148

149 reference get() { return *getStorage(); }

150 const_reference get() const { return const_cast<ErrorOr *>(this)->get(); }

151

153 return HasError ? *getErrorStorage() : std::error_code();

154 }

155

157 return toPointer(getStorage());

158 }

159

160 const_pointer operator->() const { return toPointer(getStorage()); }

161

163 return *getStorage();

164 }

165

166 const_reference operator*() const { return *getStorage(); }

167

168private:

169 template

171 if (Other.HasError) {

172

173 HasError = false;

175 } else {

176

177 HasError = true;

178 new (getErrorStorage()) std::error_code(Other.getError());

179 }

180 }

181

182 template

183 static bool compareThisIfSameType(const T1 &a, const T1 &b) {

184 return &a == &b;

185 }

186

187 template <class T1, class T2>

188 static bool compareThisIfSameType(const T1 &, const T2 &) {

189 return false;

190 }

191

192 template

194 if (compareThisIfSameType(*this, Other))

195 return;

196

199 }

200

201 template

203 if (Other.HasError) {

204

205 HasError = false;

207 } else {

208

209 HasError = true;

210 new (getErrorStorage()) std::error_code(Other.getError());

211 }

212 }

213

214 template

216 if (compareThisIfSameType(*this, Other))

217 return;

218

221 }

222

223 pointer toPointer(pointer Val) {

224 return Val;

225 }

226

227 const_pointer toPointer(const_pointer Val) const { return Val; }

228

229 pointer toPointer(wrap *Val) {

230 return &Val->get();

231 }

232

233 const_pointer toPointer(const wrap *Val) const { return &Val->get(); }

234

236 assert(!HasError && "Cannot get value when an error exists!");

238 }

239

241 assert(!HasError && "Cannot get value when an error exists!");

243 }

244

245 std::error_code *getErrorStorage() {

246 assert(HasError && "Cannot get error when a value exists!");

248 }

249

250 const std::error_code *getErrorStorage() const {

251 assert(HasError && "Cannot get error when a value exists!");

253 }

254

255 union {

258 };

259 bool HasError : 1;

260};

267 return Err.getError() == Code;

268}