diff --git a/flang/include/flang/Common/indirection.h b/flang/include/flang/Common/indirection.h index fec3bc7ae8da..a4ef615dc122 100644 --- a/flang/include/flang/Common/indirection.h +++ b/flang/include/flang/Common/indirection.h @@ -1,170 +1,170 @@ //===-- include/flang/Common/indirection.h ----------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef FORTRAN_COMMON_INDIRECTION_H_ #define FORTRAN_COMMON_INDIRECTION_H_ // Define a smart pointer class template that is rather like // non-nullable std::unique_ptr<>. Indirection<> is, like a C++ reference // type, restricted to be non-null when constructed or assigned. // Indirection<> optionally supports copy construction and copy assignment. // // To use Indirection<> with forward-referenced types, add // extern template class Fortran::common::Indirection; // outside any namespace in a header before use, and // template class Fortran::common::Indirection; // in one C++ source file later where a definition of the type is visible. #include "idioms.h" #include #include #include namespace Fortran::common { // The default case does not support (deep) copy construction or assignment. template class Indirection { public: using element_type = A; Indirection() = delete; Indirection(A *&&p) : p_{p} { CHECK(p_ && "assigning null pointer to Indirection"); p = nullptr; } Indirection(A &&x) : p_{new A(std::move(x))} {} Indirection(Indirection &&that) : p_{that.p_} { CHECK(p_ && "move construction of Indirection from null Indirection"); that.p_ = nullptr; } ~Indirection() { delete p_; p_ = nullptr; } Indirection &operator=(Indirection &&that) { CHECK(that.p_ && "move assignment of null Indirection to Indirection"); auto tmp{p_}; p_ = that.p_; that.p_ = tmp; return *this; } A &value() { return *p_; } const A &value() const { return *p_; } bool operator==(const A &that) const { return *p_ == that; } bool operator==(const Indirection &that) const { return *p_ == *that.p_; } template - static common::IfNoLvalue Make(ARGS &&... args) { + static common::IfNoLvalue Make(ARGS &&...args) { return {new A(std::move(args)...)}; } private: A *p_{nullptr}; }; // Variant with copy construction and assignment template class Indirection { public: using element_type = A; Indirection() = delete; Indirection(A *&&p) : p_{p} { CHECK(p_ && "assigning null pointer to Indirection"); p = nullptr; } Indirection(const A &x) : p_{new A(x)} {} Indirection(A &&x) : p_{new A(std::move(x))} {} Indirection(const Indirection &that) { CHECK(that.p_ && "copy construction of Indirection from null Indirection"); p_ = new A(*that.p_); } Indirection(Indirection &&that) : p_{that.p_} { CHECK(p_ && "move construction of Indirection from null Indirection"); that.p_ = nullptr; } ~Indirection() { delete p_; p_ = nullptr; } Indirection &operator=(const Indirection &that) { CHECK(that.p_ && "copy assignment of Indirection from null Indirection"); *p_ = *that.p_; return *this; } Indirection &operator=(Indirection &&that) { CHECK(that.p_ && "move assignment of null Indirection to Indirection"); auto tmp{p_}; p_ = that.p_; that.p_ = tmp; return *this; } A &value() { return *p_; } const A &value() const { return *p_; } bool operator==(const A &that) const { return *p_ == that; } bool operator==(const Indirection &that) const { return *p_ == *that.p_; } template - static common::IfNoLvalue Make(ARGS &&... args) { + static common::IfNoLvalue Make(ARGS &&...args) { return {new A(std::move(args)...)}; } private: A *p_{nullptr}; }; template using CopyableIndirection = Indirection; // A variation of std::unique_ptr<> with a reified deletion routine. // Used to avoid dependence cycles between shared libraries. template class ForwardOwningPointer { public: ForwardOwningPointer() {} ForwardOwningPointer(A *p, void (*del)(A *)) : p_{p}, deleter_{del} {} ForwardOwningPointer(ForwardOwningPointer &&that) : p_{that.p_}, deleter_{that.deleter_} { that.p_ = nullptr; } ForwardOwningPointer &operator=(ForwardOwningPointer &&that) { p_ = that.p_; that.p_ = nullptr; deleter_ = that.deleter_; return *this; } ~ForwardOwningPointer() { if (p_) { deleter_(p_); } } A &operator*() const { return *p_; } A *operator->() const { return p_; } operator bool() const { return p_ != nullptr; } A *get() { return p_; } A *release() { A *result{p_}; p_ = nullptr; return result; } void Reset(A *p, void (*del)(A *)) { if (p_) { deleter_(p_); } p_ = p; deleter_ = del; } private: A *p_{nullptr}; void (*deleter_)(A *){nullptr}; }; } // namespace Fortran::common #endif // FORTRAN_COMMON_INDIRECTION_H_ diff --git a/flang/include/flang/Common/template.h b/flang/include/flang/Common/template.h index 866292cfcf48..f31b0afa97fb 100644 --- a/flang/include/flang/Common/template.h +++ b/flang/include/flang/Common/template.h @@ -1,323 +1,323 @@ //===-- include/flang/Common/template.h -------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef FORTRAN_COMMON_TEMPLATE_H_ #define FORTRAN_COMMON_TEMPLATE_H_ #include "flang/Common/idioms.h" #include #include #include #include #include #include // Utility templates for metaprogramming and for composing the // std::optional<>, std::tuple<>, and std::variant<> containers. namespace Fortran::common { // SearchTypeList scans a list of types. The zero-based // index of the first type T in the list for which PREDICATE::value() is // true is returned, or -1 if the predicate is false for every type in the list. // This is a compile-time operation; see SearchTypes below for a run-time form. template class PREDICATE, typename TUPLE> struct SearchTypeListHelper { static constexpr int value() { if constexpr (N >= std::tuple_size_v) { return -1; } else if constexpr (PREDICATE>::value()) { return N; } else { return SearchTypeListHelper::value(); } } }; template