1 // Written in the D programming language.
2 
3 /**
4  * Interface to C++ <exception>
5  *
6  * Copyright: Copyright (c) 2016 D Language Foundation
7  * License:   $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).
8  * Authors:   $(HTTP digitalmars.com, Walter Bright)
9  *            Manu Evans
10  * Source:    $(DRUNTIMESRC core/stdcpp/_exception.d)
11  */
12 
13 module core.stdcpp.exception;
14 
15 import core.stdcpp.xutility : __cplusplus, CppStdRevision;
16 import core.attribute : weak;
17 
18 version (CppRuntime_Gcc)
19     version = GenericBaseException;
20 version (CppRuntime_Clang)
21     version = GenericBaseException;
22 version (CppRuntime_Sun)
23     version = GenericBaseException;
24 
25 extern (C++, "std"):
26 @nogc:
27 
28 ///
29 alias terminate_handler = void function() nothrow;
30 ///
31 terminate_handler set_terminate(terminate_handler f) nothrow;
32 ///
33 terminate_handler get_terminate() nothrow;
34 ///
35 void terminate() nothrow;
36 
37 static if (__cplusplus < CppStdRevision.cpp17)
38 {
39     ///
40     alias unexpected_handler = void function();
41     ///
42     deprecated unexpected_handler set_unexpected(unexpected_handler f) nothrow;
43     ///
44     deprecated unexpected_handler get_unexpected() nothrow;
45     ///
46     deprecated void unexpected();
47 }
48 
49 static if (__cplusplus < CppStdRevision.cpp17)
50 {
51     ///
52     bool uncaught_exception() nothrow;
53 }
54 else static if (__cplusplus == CppStdRevision.cpp17)
55 {
56     ///
57     deprecated bool uncaught_exception() nothrow;
58 }
59 static if (__cplusplus >= CppStdRevision.cpp17)
60 {
61     ///
62     int uncaught_exceptions() nothrow;
63 }
64 
65 version (GenericBaseException)
66 {
67     ///
68     class exception
69     {
70     @nogc:
71         ///
72         extern(D) this() nothrow {}
73         ///
74         @weak ~this() nothrow {} // HACK: this should extern, but then we have link errors!
75 
76         ///
77         @weak const(char)* what() const nothrow { return "unknown"; } // HACK: this should extern, but then we have link errors!
78 
79     protected:
80         extern(D) this(const(char)*, int = 1) nothrow { this(); } // compat with MS derived classes
81     }
82 }
83 else version (CppRuntime_DigitalMars)
84 {
85     ///
86     class exception
87     {
88     @nogc:
89         ///
90         extern(D) this() nothrow {}
91         //virtual ~this();
92         void dtor() { }     // reserve slot in vtbl[]
93 
94         ///
95         const(char)* what() const nothrow;
96 
97     protected:
98         this(const(char)*, int = 1) nothrow { this(); } // compat with MS derived classes
99     }
100 }
101 else version (CppRuntime_Microsoft)
102 {
103     ///
104     class exception
105     {
106     @nogc:
107         ///
108         extern(D) this(const(char)* message = "unknown", int = 1) nothrow { msg = message; }
109         ///
110         @weak ~this() nothrow {}
111 
112         ///
113         @weak const(char)* what() const nothrow { return msg != null ? msg : "unknown exception"; }
114 
115         // TODO: do we want this? exceptions are classes... ref types.
116 //        final ref exception opAssign(ref const(exception) e) nothrow { msg = e.msg; return this; }
117 
118     protected:
119         @weak void _Doraise() const { assert(0); }
120 
121     protected:
122         const(char)* msg;
123     }
124 
125 }
126 else
127     static assert(0, "Missing std::exception binding for this platform");
128 
129 ///
130 class bad_exception : exception
131 {
132 @nogc:
133     ///
134     extern(D) this(const(char)* message = "bad exception") nothrow { super(message); }
135 
136     version (GenericBaseException)
137     {
138         ///
139         @weak override const(char)* what() const nothrow { return "bad exception"; }
140     }
141 }