1e1df07d73c8ef575a2c7d3e34b2d6e4ba110da8
[folly.git] / folly / wangle / Try.h
1 /*
2  * Copyright 2014 Facebook, Inc.
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 namespace folly { namespace wangle {
20
21 template <class T>
22 class Try {
23   static_assert(!std::is_reference<T>::value,
24                 "Try may not be used with reference types");
25
26   enum Contains {
27     VALUE,
28     EXCEPTION,
29     NOTHING,
30   };
31
32  public:
33   typedef T element_type;
34
35   Try() : contains_(NOTHING) {}
36   explicit Try(const T& v) : contains_(VALUE), value_(v) {}
37   explicit Try(T&& v) : contains_(VALUE), value_(std::move(v)) {}
38   explicit Try(std::exception_ptr e) : contains_(EXCEPTION), e_(e) {}
39
40   // move
41   Try(Try<T>&& t);
42   Try& operator=(Try<T>&& t);
43
44   // no copy
45   Try(const Try<T>& t) = delete;
46   Try& operator=(const Try<T>& t) = delete;
47
48   ~Try();
49
50   T& value();
51   const T& value() const;
52
53   void throwIfFailed() const;
54
55   const T& operator*() const { return value(); }
56         T& operator*()       { return value(); }
57
58   const T* operator->() const { return &value(); }
59         T* operator->()       { return &value(); }
60
61   bool hasValue() const { return contains_ == VALUE; }
62   bool hasException() const { return contains_ == EXCEPTION; }
63
64  private:
65   Contains contains_;
66   union {
67     T value_;
68     std::exception_ptr e_;
69   };
70 };
71
72 template <>
73 class Try<void> {
74  public:
75   Try() : hasValue_(true) {}
76   explicit Try(std::exception_ptr e) : hasValue_(false), e_(e) {}
77
78   void value() const { throwIfFailed(); }
79   void operator*() const { return value(); }
80
81   inline void throwIfFailed() const;
82
83   bool hasValue() const { return hasValue_; }
84   bool hasException() const { return !hasValue_; }
85
86  private:
87   bool hasValue_;
88   std::exception_ptr e_;
89 };
90
91 /**
92  * Extracts value from try and returns it. Throws if try contained an exception.
93  */
94 template <typename T>
95 T moveFromTry(wangle::Try<T>&& t);
96
97 /**
98  * Throws if try contained an exception.
99  */
100 void moveFromTry(wangle::Try<void>&& t);
101
102 }}
103
104 #include "Try-inl.h"