[cfe-commits] [libcxx] r104850 - in /libcxx/trunk: include/ src/ test/language.support/support.exception/except.nested/

Howard Hinnant hhinnant at apple.com
Thu May 27 10:06:52 PDT 2010


Author: hhinnant
Date: Thu May 27 12:06:52 2010
New Revision: 104850

URL: http://llvm.org/viewvc/llvm-project?rev=104850&view=rev
Log:
[except.nested]

Added:
    libcxx/trunk/test/language.support/support.exception/except.nested/assign.pass.cpp
    libcxx/trunk/test/language.support/support.exception/except.nested/ctor_copy.pass.cpp
    libcxx/trunk/test/language.support/support.exception/except.nested/ctor_default.pass.cpp
    libcxx/trunk/test/language.support/support.exception/except.nested/rethrow_if_nested.pass.cpp
    libcxx/trunk/test/language.support/support.exception/except.nested/rethrow_nested.pass.cpp
    libcxx/trunk/test/language.support/support.exception/except.nested/throw_with_nested.pass.cpp
Modified:
    libcxx/trunk/include/exception
    libcxx/trunk/src/exception.cpp

Modified: libcxx/trunk/include/exception
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/exception?rev=104850&r1=104849&r2=104850&view=diff
==============================================================================
--- libcxx/trunk/include/exception (original)
+++ libcxx/trunk/include/exception Thu May 27 12:06:52 2010
@@ -76,6 +76,7 @@
 
 #include <__config>
 #include <cstddef>
+#include <type_traits>
 
 #pragma GCC system_header
 
@@ -150,6 +151,83 @@
     }
 }
 
+// nested_exception
+
+class _LIBCPP_EXCEPTION_ABI nested_exception
+{
+    exception_ptr __ptr_;
+public:
+    nested_exception();
+//     nested_exception(const nested_exception&) throw() = default;
+//     nested_exception& operator=(const nested_exception&) throw() = default;
+    virtual ~nested_exception();
+
+    // access functions
+    void rethrow_nested /*[[noreturn]]*/ () const;
+    exception_ptr nested_ptr() const {return __ptr_;}
+};
+
+template <class _Tp>
+struct __nested
+    : public _Tp,
+      public nested_exception
+{
+    explicit __nested(const _Tp& __t) : _Tp(__t) {}
+};
+
+template <class _Tp>
+void 
+#ifdef _LIBCPP_MOVE
+throw_with_nested /*[[noreturn]]*/ (_Tp&& __t, typename enable_if<
+                  is_class<typename remove_reference<_Tp>::type>::value &&
+                  !is_base_of<nested_exception, typename remove_reference<_Tp>::type>::value
+                                    >::type* = 0)
+#else
+throw_with_nested (_Tp& __t, typename enable_if<
+                  is_class<_Tp>::value && !is_base_of<nested_exception, _Tp>::value
+                                    >::type* = 0)
+#endif
+{
+    throw __nested<typename remove_reference<_Tp>::type>(_STD::forward<_Tp>(__t));
+}
+
+template <class _Tp>
+void 
+#ifdef _LIBCPP_MOVE
+throw_with_nested /*[[noreturn]]*/ (_Tp&& __t, typename enable_if<
+                  !is_class<typename remove_reference<_Tp>::type>::value ||
+                  is_base_of<nested_exception, typename remove_reference<_Tp>::type>::value
+                                    >::type* = 0)
+#else
+throw_with_nested (_Tp& __t, typename enable_if<
+                  !is_class<_Tp>::value || is_base_of<nested_exception, _Tp>::value
+                                    >::type* = 0)
+#endif
+{
+    throw _STD::forward<_Tp>(__t);
+}
+
+template <class _E>
+inline
+void
+rethrow_if_nested(const _E& __e, typename enable_if<
+                                   !is_same<_E, nested_exception>::value &&
+                                   is_convertible<_E*, nested_exception*>::value
+                                                   >::type* = 0)
+{
+    static_cast<const nested_exception&>(__e).rethrow_nested();
+}
+
+template <class _E>
+inline
+void
+rethrow_if_nested(const _E& __e, typename enable_if<
+                                   is_same<_E, nested_exception>::value ||
+                                   !is_convertible<_E*, nested_exception*>::value
+                                                   >::type* = 0)
+{
+}
+
 }  // std
 
 #endif  // _LIBCPP_EXCEPTION

Modified: libcxx/trunk/src/exception.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/exception.cpp?rev=104850&r1=104849&r2=104850&view=diff
==============================================================================
--- libcxx/trunk/src/exception.cpp (original)
+++ libcxx/trunk/src/exception.cpp Thu May 27 12:06:52 2010
@@ -142,6 +142,23 @@
 #endif
 }
 
+nested_exception::nested_exception()
+    : __ptr_(current_exception())
+{
+}
+
+nested_exception::~nested_exception()
+{
+}
+
+void
+nested_exception::rethrow_nested /*[[noreturn]]*/ () const
+{
+    if (__ptr_ == nullptr)
+        terminate();
+    rethrow_exception(__ptr_);
+}
+
 } // std
 
 

Added: libcxx/trunk/test/language.support/support.exception/except.nested/assign.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/language.support/support.exception/except.nested/assign.pass.cpp?rev=104850&view=auto
==============================================================================
--- libcxx/trunk/test/language.support/support.exception/except.nested/assign.pass.cpp (added)
+++ libcxx/trunk/test/language.support/support.exception/except.nested/assign.pass.cpp Thu May 27 12:06:52 2010
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <exception>
+
+// class nested_exception;
+
+// nested_exception& operator=(const nested_exception&) throw() = default;
+
+#include <exception>
+#include <cassert>
+
+class A
+{
+    int data_;
+public:
+    explicit A(int data) : data_(data) {}
+
+    friend bool operator==(const A& x, const A& y) {return x.data_ == y.data_;}
+};
+
+int main()
+{
+    {
+        std::nested_exception e0;
+        std::nested_exception e;
+        e = e0;
+        assert(e.nested_ptr() == nullptr);
+    }
+    {
+        try
+        {
+            throw A(2);
+            assert(false);
+        }
+        catch (const A&)
+        {
+            std::nested_exception e0;
+            std::nested_exception e;
+            e = e0;
+            assert(e.nested_ptr() != nullptr);
+            try
+            {
+                rethrow_exception(e.nested_ptr());
+                assert(false);
+            }
+            catch (const A& a)
+            {
+                assert(a == A(2));
+            }
+        }
+    }
+}

Added: libcxx/trunk/test/language.support/support.exception/except.nested/ctor_copy.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/language.support/support.exception/except.nested/ctor_copy.pass.cpp?rev=104850&view=auto
==============================================================================
--- libcxx/trunk/test/language.support/support.exception/except.nested/ctor_copy.pass.cpp (added)
+++ libcxx/trunk/test/language.support/support.exception/except.nested/ctor_copy.pass.cpp Thu May 27 12:06:52 2010
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <exception>
+
+// class nested_exception;
+
+// nested_exception(const nested_exception&) throw() = default;
+
+#include <exception>
+#include <cassert>
+
+class A
+{
+    int data_;
+public:
+    explicit A(int data) : data_(data) {}
+
+    friend bool operator==(const A& x, const A& y) {return x.data_ == y.data_;}
+};
+
+int main()
+{
+    {
+        std::nested_exception e0;
+        std::nested_exception e = e0;
+        assert(e.nested_ptr() == nullptr);
+    }
+    {
+        try
+        {
+            throw A(2);
+            assert(false);
+        }
+        catch (const A&)
+        {
+            std::nested_exception e0;
+            std::nested_exception e = e0;
+            assert(e.nested_ptr() != nullptr);
+            try
+            {
+                rethrow_exception(e.nested_ptr());
+                assert(false);
+            }
+            catch (const A& a)
+            {
+                assert(a == A(2));
+            }
+        }
+    }
+}

Added: libcxx/trunk/test/language.support/support.exception/except.nested/ctor_default.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/language.support/support.exception/except.nested/ctor_default.pass.cpp?rev=104850&view=auto
==============================================================================
--- libcxx/trunk/test/language.support/support.exception/except.nested/ctor_default.pass.cpp (added)
+++ libcxx/trunk/test/language.support/support.exception/except.nested/ctor_default.pass.cpp Thu May 27 12:06:52 2010
@@ -0,0 +1,55 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <exception>
+
+// class nested_exception;
+
+// nested_exception() throw();
+
+#include <exception>
+#include <cassert>
+
+class A
+{
+    int data_;
+public:
+    explicit A(int data) : data_(data) {}
+
+    friend bool operator==(const A& x, const A& y) {return x.data_ == y.data_;}
+};
+
+int main()
+{
+    {
+        std::nested_exception e;
+        assert(e.nested_ptr() == nullptr);
+    }
+    {
+        try
+        {
+            throw A(2);
+            assert(false);
+        }
+        catch (const A&)
+        {
+            std::nested_exception e;
+            assert(e.nested_ptr() != nullptr);
+            try
+            {
+                rethrow_exception(e.nested_ptr());
+                assert(false);
+            }
+            catch (const A& a)
+            {
+                assert(a == A(2));
+            }
+        }
+    }
+}

Added: libcxx/trunk/test/language.support/support.exception/except.nested/rethrow_if_nested.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/language.support/support.exception/except.nested/rethrow_if_nested.pass.cpp?rev=104850&view=auto
==============================================================================
--- libcxx/trunk/test/language.support/support.exception/except.nested/rethrow_if_nested.pass.cpp (added)
+++ libcxx/trunk/test/language.support/support.exception/except.nested/rethrow_if_nested.pass.cpp Thu May 27 12:06:52 2010
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <exception>
+
+// class nested_exception;
+
+// template <class E> void rethrow_if_nested(const E& e);
+
+#include <exception>
+#include <cstdlib>
+#include <cassert>
+
+class A
+{
+    int data_;
+public:
+    explicit A(int data) : data_(data) {}
+
+    friend bool operator==(const A& x, const A& y) {return x.data_ == y.data_;}
+};
+
+class B
+    : public std::nested_exception
+{
+    int data_;
+public:
+    explicit B(int data) : data_(data) {}
+    B(const B& b) : data_(b.data_) {}
+
+    friend bool operator==(const B& x, const B& y) {return x.data_ == y.data_;}
+};
+
+int main()
+{
+    {
+        try
+        {
+            A a(3);
+            std::rethrow_if_nested(a);
+            assert(true);
+        }
+        catch (...)
+        {
+            assert(false);
+        }
+    }
+    {
+        try
+        {
+            throw B(5);
+        }
+        catch (const B& b0)
+        {
+            try
+            {
+                B b = b0;
+                std::rethrow_if_nested(b);
+                assert(false);
+            }
+            catch (const B& b)
+            {
+                assert(b == B(5));
+            }
+        }
+    }
+}

Added: libcxx/trunk/test/language.support/support.exception/except.nested/rethrow_nested.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/language.support/support.exception/except.nested/rethrow_nested.pass.cpp?rev=104850&view=auto
==============================================================================
--- libcxx/trunk/test/language.support/support.exception/except.nested/rethrow_nested.pass.cpp (added)
+++ libcxx/trunk/test/language.support/support.exception/except.nested/rethrow_nested.pass.cpp Thu May 27 12:06:52 2010
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <exception>
+
+// class nested_exception;
+
+// void rethrow_nested [[noreturn]] () const;
+
+#include <exception>
+#include <cstdlib>
+#include <cassert>
+
+class A
+{
+    int data_;
+public:
+    explicit A(int data) : data_(data) {}
+
+    friend bool operator==(const A& x, const A& y) {return x.data_ == y.data_;}
+};
+
+void go_quietly()
+{
+    std::exit(0);
+}
+
+int main()
+{
+    {
+        try
+        {
+            throw A(2);
+            assert(false);
+        }
+        catch (const A&)
+        {
+            const std::nested_exception e;
+            assert(e.nested_ptr() != nullptr);
+            try
+            {
+                e.rethrow_nested();
+                assert(false);
+            }
+            catch (const A& a)
+            {
+                assert(a == A(2));
+            }
+        }
+    }
+    {
+        try
+        {
+            std::set_terminate(go_quietly);
+            const std::nested_exception e;
+            e.rethrow_nested();
+            assert(false);
+        }
+        catch (...)
+        {
+            assert(false);
+        }
+    }
+}

Added: libcxx/trunk/test/language.support/support.exception/except.nested/throw_with_nested.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/language.support/support.exception/except.nested/throw_with_nested.pass.cpp?rev=104850&view=auto
==============================================================================
--- libcxx/trunk/test/language.support/support.exception/except.nested/throw_with_nested.pass.cpp (added)
+++ libcxx/trunk/test/language.support/support.exception/except.nested/throw_with_nested.pass.cpp Thu May 27 12:06:52 2010
@@ -0,0 +1,103 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <exception>
+
+// class nested_exception;
+
+// template<class T> void throw_with_nested [[noreturn]] (T&& t);
+
+#include <exception>
+#include <cstdlib>
+#include <cassert>
+
+class A
+{
+    int data_;
+public:
+    explicit A(int data) : data_(data) {}
+
+    friend bool operator==(const A& x, const A& y) {return x.data_ == y.data_;}
+};
+
+class B
+    : public std::nested_exception
+{
+    int data_;
+public:
+    explicit B(int data) : data_(data) {}
+
+    friend bool operator==(const B& x, const B& y) {return x.data_ == y.data_;}
+};
+
+int main()
+{
+    {
+        try
+        {
+            A a(3);
+            std::throw_with_nested(a);
+            assert(false);
+        }
+        catch (const A& a)
+        {
+            assert(a == A(3));
+        }
+    }
+    {
+        try
+        {
+            A a(4);
+            std::throw_with_nested(a);
+            assert(false);
+        }
+        catch (const std::nested_exception& e)
+        {
+            assert(e.nested_ptr() == nullptr);
+        }
+    }
+    {
+        try
+        {
+            B b(5);
+            std::throw_with_nested(b);
+            assert(false);
+        }
+        catch (const B& b)
+        {
+            assert(b == B(5));
+        }
+    }
+    {
+        try
+        {
+            B b(6);
+            std::throw_with_nested(b);
+            assert(false);
+        }
+        catch (const std::nested_exception& e)
+        {
+            assert(e.nested_ptr() == nullptr);
+            const B& b = dynamic_cast<const B&>(e);
+            assert(b == B(6));
+        }
+    }
+    {
+        try
+        {
+            int i = 7;
+            std::throw_with_nested(i);
+            assert(false);
+        }
+        catch (int i)
+        {
+            assert(i == 7);
+        }
+    }
+}





More information about the cfe-commits mailing list