X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FIndestructible.h;h=ad1d21cbfeb3fcf06139215d385d69e6930fd64f;hb=37ce60726a249bb67c885236a45d50cdb781694e;hp=15e03c9d020257688d868b44a89913926821901f;hpb=a955532d8b3038333c7a73a07c3c1727d8413028;p=folly.git diff --git a/folly/Indestructible.h b/folly/Indestructible.h index 15e03c9d..ad1d21cb 100644 --- a/folly/Indestructible.h +++ b/folly/Indestructible.h @@ -1,5 +1,5 @@ /* - * Copyright 2016 Facebook, Inc. + * Copyright 2017 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +16,8 @@ #pragma once +#include #include -#include -#include -#include namespace folly { @@ -60,10 +58,13 @@ template class Indestructible final { public: - template + template + constexpr Indestructible() noexcept(noexcept(T())) {} + + template ()...))> explicit constexpr Indestructible(Args&&... args) noexcept( - std::is_nothrow_constructible::value) - : storage_(std::forward(args)...), inited_(true) {} + noexcept(T(std::declval()...))) + : storage_(std::forward(args)...) {} ~Indestructible() = default; @@ -71,51 +72,51 @@ class Indestructible final { Indestructible& operator=(Indestructible const&) = delete; Indestructible(Indestructible&& other) noexcept( - std::is_nothrow_move_constructible::value) + noexcept(T(std::declval()))) : storage_(std::move(other.storage_.value)) { - other.inited_ = false; + other.erased_ = true; } Indestructible& operator=(Indestructible&& other) noexcept( - std::is_nothrow_move_assignable::value) { + noexcept(T(std::declval()))) { storage_.value = std::move(other.storage_.value); - other.inited_ = false; + other.erased_ = true; } - T* get() { + T* get() noexcept { check(); return &storage_.value; } - T const* get() const { + T const* get() const noexcept { check(); return &storage_.value; } - T& operator*() { return *get(); } - T const& operator*() const { return *get(); } - T* operator->() { return get(); } - T const* operator->() const { return get(); } + T& operator*() noexcept { return *get(); } + T const& operator*() const noexcept { return *get(); } + T* operator->() noexcept { return get(); } + T const* operator->() const noexcept { return get(); } private: - void check() const { - if (UNLIKELY(!inited_)) { - fail(); - } - } - - [[noreturn]] FOLLY_NOINLINE static void fail() { - LOG(FATAL) << "Indestructible is not initialized"; + void check() const noexcept { + assert(!erased_); } union Storage { T value; - template - explicit constexpr Storage(Args&&... args) + template + constexpr Storage() noexcept(noexcept(T())) : value() {} + + template < + typename... Args, + typename = decltype(T(std::declval()...))> + explicit constexpr Storage(Args&&... args) noexcept( + noexcept(T(std::declval()...))) : value(std::forward(args)...) {} ~Storage() {} }; - Storage storage_; - bool inited_{false}; + Storage storage_{}; + bool erased_{false}; }; }