Add an emplace(...) method to llvm::Optional<T>.
[oota-llvm.git] / include / llvm / ADT / Optional.h
index 0386e57f05f44b8f86010e3b59dbe9102312a2b9..591872e6591a03c65e6774276e82eeeaffa542e8 100644 (file)
@@ -20,6 +20,7 @@
 #include "llvm/Support/AlignOf.h"
 #include "llvm/Support/Compiler.h"
 #include <cassert>
+#include <new>
 #include <utility>
 
 namespace llvm {
@@ -69,6 +70,61 @@ public:
     return *this;
   }
 
+#if LLVM_HAS_VARIADIC_TEMPLATES
+
+  /// Create a new object by constructing it in place with the given arguments.
+  template<typename ...ArgTypes>
+  void emplace(ArgTypes &&...Args) {
+    reset();
+    hasVal = true;
+    new (storage.buffer) T(std::forward<ArgTypes>(Args)...);
+  }
+
+#else
+  
+  /// Create a new object by default-constructing it in place.
+  void emplace() {
+    reset();
+    hasVal = true;
+    new (storage.buffer) T();
+  }
+  
+  /// Create a new object by constructing it in place with the given arguments.
+  template<typename T1>
+  void emplace(T1 &&A1) {
+    reset();
+    hasVal = true;
+    new (storage.buffer) T(std::forward<T1>(A1));
+  }
+  
+  /// Create a new object by constructing it in place with the given arguments.
+  template<typename T1, typename T2>
+  void emplace(T1 &&A1, T2 &&A2) {
+    reset();
+    hasVal = true;
+    new (storage.buffer) T(std::forward<T1>(A1), std::forward<T2>(A2));
+  }
+  
+  /// Create a new object by constructing it in place with the given arguments.
+  template<typename T1, typename T2, typename T3>
+  void emplace(T1 &&A1, T2 &&A2, T3 &&A3) {
+    reset();
+    hasVal = true;
+    new (storage.buffer) T(std::forward<T1>(A1), std::forward<T2>(A2),
+        std::forward<T3>(A3));
+  }
+  
+  /// Create a new object by constructing it in place with the given arguments.
+  template<typename T1, typename T2, typename T3, typename T4>
+  void emplace(T1 &&A1, T2 &&A2, T3 &&A3, T4 &&A4) {
+    reset();
+    hasVal = true;
+    new (storage.buffer) T(std::forward<T1>(A1), std::forward<T2>(A2),
+        std::forward<T3>(A3), std::forward<T4>(A4));
+  }
+
+#endif // LLVM_HAS_VARIADIC_TEMPLATES
+
   static inline Optional create(const T* y) {
     return y ? Optional(*y) : Optional();
   }