summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/result.h58
1 files changed, 16 insertions, 42 deletions
diff --git a/src/core/hle/result.h b/src/core/hle/result.h
index 0fce5988b..69613fbbb 100644
--- a/src/core/hle/result.h
+++ b/src/core/hle/result.h
@@ -269,7 +269,6 @@ public:
269 : result_code(error_code) 269 : result_code(error_code)
270 { 270 {
271 ASSERT(error_code.IsError()); 271 ASSERT(error_code.IsError());
272 UpdateDebugPtr();
273 } 272 }
274 273
275 /** 274 /**
@@ -287,40 +286,37 @@ public:
287 : result_code(o.result_code) 286 : result_code(o.result_code)
288 { 287 {
289 if (!o.empty()) { 288 if (!o.empty()) {
290 new (&storage) T(*o.GetPointer()); 289 new (&object) T(o.object);
291 } 290 }
292 UpdateDebugPtr();
293 } 291 }
294 292
295 ResultVal(ResultVal&& o) 293 ResultVal(ResultVal&& o)
296 : result_code(o.result_code) 294 : result_code(o.result_code)
297 { 295 {
298 if (!o.empty()) { 296 if (!o.empty()) {
299 new (&storage) T(std::move(*o.GetPointer())); 297 new (&object) T(std::move(o.object));
300 } 298 }
301 UpdateDebugPtr();
302 } 299 }
303 300
304 ~ResultVal() { 301 ~ResultVal() {
305 if (!empty()) { 302 if (!empty()) {
306 GetPointer()->~T(); 303 object.~T();
307 } 304 }
308 } 305 }
309 306
310 ResultVal& operator=(const ResultVal& o) { 307 ResultVal& operator=(const ResultVal& o) {
311 if (!empty()) { 308 if (!empty()) {
312 if (!o.empty()) { 309 if (!o.empty()) {
313 *GetPointer() = *o.GetPointer(); 310 object = o.object;
314 } else { 311 } else {
315 GetPointer()->~T(); 312 object.~T();
316 } 313 }
317 } else { 314 } else {
318 if (!o.empty()) { 315 if (!o.empty()) {
319 new (&storage) T(*o.GetPointer()); 316 new (&object) T(o.object);
320 } 317 }
321 } 318 }
322 result_code = o.result_code; 319 result_code = o.result_code;
323 UpdateDebugPtr();
324 320
325 return *this; 321 return *this;
326 } 322 }
@@ -333,11 +329,10 @@ public:
333 void emplace(ResultCode success_code, Args&&... args) { 329 void emplace(ResultCode success_code, Args&&... args) {
334 ASSERT(success_code.IsSuccess()); 330 ASSERT(success_code.IsSuccess());
335 if (!empty()) { 331 if (!empty()) {
336 GetPointer()->~T(); 332 object.~T();
337 } 333 }
338 new (&storage) T(std::forward<Args>(args)...); 334 new (&object) T(std::forward<Args>(args)...);
339 result_code = success_code; 335 result_code = success_code;
340 UpdateDebugPtr();
341 } 336 }
342 337
343 /// Returns true if the `ResultVal` contains an error code and no value. 338 /// Returns true if the `ResultVal` contains an error code and no value.
@@ -350,15 +345,15 @@ public:
350 345
351 ResultCode Code() const { return result_code; } 346 ResultCode Code() const { return result_code; }
352 347
353 const T& operator* () const { return *GetPointer(); } 348 const T& operator* () const { return object; }
354 T& operator* () { return *GetPointer(); } 349 T& operator* () { return object; }
355 const T* operator->() const { return GetPointer(); } 350 const T* operator->() const { return &object; }
356 T* operator->() { return GetPointer(); } 351 T* operator->() { return &object; }
357 352
358 /// Returns the value contained in this `ResultVal`, or the supplied default if it is missing. 353 /// Returns the value contained in this `ResultVal`, or the supplied default if it is missing.
359 template <typename U> 354 template <typename U>
360 T ValueOr(U&& value) const { 355 T ValueOr(U&& value) const {
361 return !empty() ? *GetPointer() : std::move(value); 356 return !empty() ? object : std::move(value);
362 } 357 }
363 358
364 /// Asserts that the result succeeded and returns a reference to it. 359 /// Asserts that the result succeeded and returns a reference to it.
@@ -372,31 +367,10 @@ public:
372 } 367 }
373 368
374private: 369private:
375 typedef typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type StorageType; 370 // A union is used to allocate the storage for the value, while allowing us to construct and
376 371 // destruct it at will.
377 StorageType storage; 372 union { T object; };
378 ResultCode result_code; 373 ResultCode result_code;
379#ifdef _DEBUG
380 // The purpose of this pointer is to aid inspecting the type with a debugger, eliminating the
381 // need to cast `storage` to a pointer or pay attention to `result_code`.
382 const T* debug_ptr;
383#endif
384
385 void UpdateDebugPtr() {
386#ifdef _DEBUG
387 debug_ptr = empty() ? nullptr : static_cast<const T*>(static_cast<const void*>(&storage));
388#endif
389 }
390
391 const T* GetPointer() const {
392 ASSERT(!empty());
393 return static_cast<const T*>(static_cast<const void*>(&storage));
394 }
395
396 T* GetPointer() {
397 ASSERT(!empty());
398 return static_cast<T*>(static_cast<void*>(&storage));
399 }
400}; 374};
401 375
402/** 376/**