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
13module core.stdcpp.exception;
14
15import core.stdcpp.xutility : __cplusplus, CppStdRevision;
16import core.attribute : weak;
17
18version (CppRuntime_Gcc)
19    version = GenericBaseException;
20version (CppRuntime_Clang)
21    version = GenericBaseException;
22version (CppRuntime_Sun)
23    version = GenericBaseException;
24
25extern (C++, "std"):
26@nogc:
27
28///
29alias terminate_handler = void function() nothrow;
30///
31terminate_handler set_terminate(terminate_handler f) nothrow;
32///
33terminate_handler get_terminate() nothrow;
34///
35void terminate() nothrow;
36
37static 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
49static if (__cplusplus < CppStdRevision.cpp17)
50{
51    ///
52    bool uncaught_exception() nothrow;
53}
54else static if (__cplusplus == CppStdRevision.cpp17)
55{
56    ///
57    deprecated bool uncaught_exception() nothrow;
58}
59static if (__cplusplus >= CppStdRevision.cpp17)
60{
61    ///
62    int uncaught_exceptions() nothrow;
63}
64
65version (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}
83else 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}
101else 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}
126else
127    static assert(0, "Missing std::exception binding for this platform");
128
129///
130class 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}
142