PageRenderTime 85ms CodeModel.GetById 68ms app.highlight 13ms RepoModel.GetById 1ms app.codeStats 0ms

/_3rdParty/dlib/error.h

https://bitbucket.org/byzhang/mldemos
C Header | 420 lines | 221 code | 46 blank | 153 comment | 104 complexity | 9e3d78ceeb48b60aac6c8d6bc27c6bb5 MD5 | raw file
  1// Copyright (C) 2003  Davis E. King (davis@dlib.net)
  2// License: Boost Software License   See LICENSE.txt for the full license.
  3#ifndef DLIB_ERROr_ 
  4#define DLIB_ERROr_ 
  5
  6#include <string>
  7#include <new>          // for std::bad_alloc
  8#include <iostream>
  9#include <cassert>
 10#include <cstdlib>
 11#include <exception>
 12
 13// -------------------------------
 14// ------ exception classes ------
 15// -------------------------------
 16
 17namespace dlib
 18{
 19
 20// ----------------------------------------------------------------------------------------
 21
 22    enum error_type
 23    {
 24        EOTHER,        
 25        EPORT_IN_USE,  
 26        ETIMEOUT,     
 27        ECONNECTION, 
 28        ELISTENER, 
 29        ERESOLVE,     
 30        EMONITOR,   
 31        ECREATE_THREAD,    
 32        ECREATE_MUTEX,    
 33        ECREATE_SIGNALER,
 34        EUNSPECIFIED,   
 35        EGENERAL_TYPE1,
 36        EGENERAL_TYPE2,  
 37        EGENERAL_TYPE3,  
 38        EINVALID_OPTION,
 39        ETOO_FEW_ARGS,
 40        ETOO_MANY_ARGS,
 41        ESOCKET,
 42        ETHREAD,
 43        EGUI,
 44        EFATAL,
 45        EBROKEN_ASSERT,
 46        EIMAGE_LOAD,
 47        EDIR_CREATE,
 48        EINCOMPATIBLE_OPTIONS,
 49        EMISSING_REQUIRED_OPTION,
 50        EINVALID_OPTION_ARG,
 51        EMULTIPLE_OCCURANCES,
 52        ECONFIG_READER,
 53        EIMAGE_SAVE,
 54        ECAST_TO_STRING,
 55        ESTRING_CAST,
 56        EUTF8_TO_UTF32
 57    };
 58
 59// ----------------------------------------------------------------------------------------
 60
 61    // the base exception class
 62    class error : public std::exception
 63    {
 64        /*!
 65            WHAT THIS OBJECT REPRESENTS
 66                This is the base exception class for the dlib library.  i.e. all 
 67                exceptions in this library inherit from this class.
 68        !*/
 69
 70    public:
 71        error(
 72            error_type t,
 73            const std::string& a
 74        ): info(a), type(t) {}
 75        /*!
 76            ensures
 77                - #type == t
 78                - #info == a
 79        !*/
 80
 81        error(
 82            error_type t
 83        ): type(t) {}
 84        /*!
 85            ensures
 86                - #type == t
 87                - #info == ""
 88        !*/
 89
 90        error(
 91            const std::string& a
 92        ): info(a), type(EUNSPECIFIED) {}
 93        /*!
 94            ensures
 95                - #type == EUNSPECIFIED
 96                - #info == a
 97        !*/
 98
 99        error(
100        ): type(EUNSPECIFIED) {}
101        /*!
102            ensures
103                - #type == EUNSPECIFIED
104                - #info == ""
105        !*/
106
107        virtual ~error(
108        ) throw() {}
109        /*!
110            ensures
111                - does nothing
112        !*/
113
114        const char* what(
115        ) const throw()
116        /*!
117            ensures
118                - if (info.size() != 0) then
119                    - returns info.c_str()
120                - else
121                    - returns type_to_string(type)
122        !*/
123        {
124            if (info.size() > 0)
125                return info.c_str(); 
126            else
127                return type_to_string();
128        }
129
130        const char* type_to_string (
131        ) const throw()
132        /*!
133            ensures
134                - returns a string that names the contents of the type member.
135        !*/
136        {
137            if (type == EOTHER) return "EOTHER";
138            else if ( type == EPORT_IN_USE) return "EPORT_IN_USE";
139            else if ( type == ETIMEOUT) return "ETIMEOUT";
140            else if ( type == ECONNECTION) return "ECONNECTION"; 
141            else if ( type == ELISTENER) return "ELISTENER"; 
142            else if ( type == ERESOLVE) return "ERESOLVE";     
143            else if ( type == EMONITOR) return "EMONITOR";   
144            else if ( type == ECREATE_THREAD) return "ECREATE_THREAD";    
145            else if ( type == ECREATE_MUTEX) return "ECREATE_MUTEX";    
146            else if ( type == ECREATE_SIGNALER) return "ECREATE_SIGNALER";
147            else if ( type == EUNSPECIFIED) return "EUNSPECIFIED";   
148            else if ( type == EGENERAL_TYPE1) return "EGENERAL_TYPE1";
149            else if ( type == EGENERAL_TYPE2) return "EGENERAL_TYPE2";  
150            else if ( type == EGENERAL_TYPE3) return "EGENERAL_TYPE3";  
151            else if ( type == EINVALID_OPTION) return "EINVALID_OPTION";
152            else if ( type == ETOO_FEW_ARGS) return "ETOO_FEW_ARGS";
153            else if ( type == ETOO_MANY_ARGS) return "ETOO_MANY_ARGS";
154            else if ( type == ESOCKET) return "ESOCKET";
155            else if ( type == ETHREAD) return "ETHREAD";
156            else if ( type == EGUI) return "EGUI";
157            else if ( type == EFATAL) return "EFATAL";
158            else if ( type == EBROKEN_ASSERT) return "EBROKEN_ASSERT";
159            else if ( type == EIMAGE_LOAD) return "EIMAGE_LOAD";
160            else if ( type == EDIR_CREATE) return "EDIR_CREATE";
161            else if ( type == EINCOMPATIBLE_OPTIONS) return "EINCOMPATIBLE_OPTIONS";
162            else if ( type == EMISSING_REQUIRED_OPTION) return "EMISSING_REQUIRED_OPTION";
163            else if ( type == EINVALID_OPTION_ARG) return "EINVALID_OPTION_ARG";
164            else if ( type == EMULTIPLE_OCCURANCES) return "EMULTIPLE_OCCURANCES";
165            else if ( type == ECONFIG_READER) return "ECONFIG_READER";
166            else if ( type == EIMAGE_SAVE) return "EIMAGE_SAVE";
167            else if ( type == ECAST_TO_STRING) return "ECAST_TO_STRING";
168            else if ( type == ESTRING_CAST) return "ESTRING_CAST";
169            else if ( type == EUTF8_TO_UTF32) return "EUTF8_TO_UTF32";
170            else return "undefined error type";
171        }
172
173        const std::string info;  // info about the error
174        const error_type type; // the type of the error
175
176    private:
177        const error& operator=(const error&);
178    };
179
180// ----------------------------------------------------------------------------------------
181
182    class fatal_error : public error
183    {
184        /*!
185            WHAT THIS OBJECT REPRESENTS
186                As the name says, this object represents some kind of fatal error.  
187                That is, it represents an unrecoverable error and any program that
188                throws this exception is, by definition, buggy and needs to be fixed.
189
190                Note that a fatal_error exception can only be thrown once.  The second
191                time an application attempts to construct a fatal_error it will be 
192                immediately aborted and an error message will be printed to std::cerr. 
193                The reason for this is because the first fatal_error was apparently ignored
194                so the second fatal_error is going to make itself impossible to ignore 
195                by calling abort.  The lesson here is that you should not try to ignore 
196                fatal errors.
197
198                This is also the exception thrown by the DLIB_ASSERT and DLIB_CASSERT macros.
199        !*/
200
201    public:
202        fatal_error(
203            error_type t,
204            const std::string& a
205        ): error(t,a) {check_for_previous_fatal_errors();}
206        /*!
207            ensures
208                - #type == t
209                - #info == a
210        !*/
211
212        fatal_error(
213            error_type t
214        ): error(t) {check_for_previous_fatal_errors();}
215        /*!
216            ensures
217                - #type == t
218                - #info == ""
219        !*/
220
221        fatal_error(
222            const std::string& a
223        ): error(EFATAL,a) {check_for_previous_fatal_errors();}
224        /*!
225            ensures
226                - #type == EFATAL
227                - #info == a
228        !*/
229
230        fatal_error(
231        ): error(EFATAL) {check_for_previous_fatal_errors();}
232        /*!
233            ensures
234                - #type == EFATAL
235                - #info == ""
236        !*/
237
238    private:
239
240        static inline char* message ()
241        { 
242            static char buf[2000];
243            buf[1999] = '\0'; // just to be extra safe
244            return buf;
245        }
246
247        static inline void dlib_fatal_error_terminate (
248        )
249        {
250            std::cerr << "\n**************************** FATAL ERROR DETECTED ****************************";
251            std::cerr << message() << "\n";
252            std::cerr << "******************************************************************************\n" << "\n";
253        }
254
255        void check_for_previous_fatal_errors()
256        {
257            static bool is_first_fatal_error = true;
258            if (is_first_fatal_error == false)
259            {
260                std::cerr << "\n\n ************************** FATAL ERROR DETECTED ************************** " << "\n";
261                std::cerr << " ************************** FATAL ERROR DETECTED ************************** " << "\n";
262                std::cerr << " ************************** FATAL ERROR DETECTED ************************** \n" << "\n";
263                std::cerr << "Two fatal errors have been detected, the first was inappropriately ignored. \n"
264                          << "To prevent further fatal errors from being ignored this application will be \n"
265                          << "terminated immediately and you should go fix this buggy program.\n\n"
266                          << "The error message from this fatal error was:\n" << this->what() << "\n\n" << "\n";
267                using namespace std;
268                assert(false);
269                abort();
270            }
271            else
272            {
273                // copy the message into the fixed message buffer so that it can be recalled by dlib_fatal_error_terminate
274                // if needed.
275                char* msg = message();
276                unsigned long i;
277                for (i = 0; i < 2000-1 && i < this->info.size(); ++i)
278                    msg[i] = info[i];
279                msg[i] = '\0';
280
281                // set this termination handler so that if the user doesn't catch this dlib::fatal_error that is being
282                // thrown then it will eventually be printed to standard error
283                std::set_terminate(&dlib_fatal_error_terminate);
284            }
285            is_first_fatal_error = false;
286        }
287    };
288
289// ----------------------------------------------------------------------------------------
290
291    class gui_error : public error
292    {
293    public:
294        gui_error(
295            error_type t,
296            const std::string& a
297        ): error(t,a) {}
298        /*!
299            ensures
300                - #type == t
301                - #info == a
302        !*/
303
304        gui_error(
305            error_type t
306        ): error(t) {}
307        /*!
308            ensures
309                - #type == t
310                - #info == ""
311        !*/
312
313        gui_error(
314            const std::string& a
315        ): error(EGUI,a) {}
316        /*!
317            ensures
318                - #type == EGUI 
319                - #info == a
320        !*/
321
322        gui_error(
323        ): error(EGUI) {}
324        /*!
325            ensures
326                - #type == EGUI
327                - #info == ""
328        !*/
329    };
330
331// ----------------------------------------------------------------------------------------
332
333    class socket_error : public error
334    {
335    public:
336        socket_error(
337            error_type t,
338            const std::string& a
339        ): error(t,a) {}
340        /*!
341            ensures
342                - #type == t
343                - #info == a
344        !*/
345
346        socket_error(
347            error_type t
348        ): error(t) {}
349        /*!
350            ensures
351                - #type == t
352                - #info == ""
353        !*/
354
355        socket_error(
356            const std::string& a
357        ): error(ESOCKET,a) {}
358        /*!
359            ensures
360                - #type == ESOCKET
361                - #info == a
362        !*/
363
364        socket_error(
365        ): error(ESOCKET) {}
366        /*!
367            ensures
368                - #type == ESOCKET
369                - #info == ""
370        !*/
371    };
372
373// ----------------------------------------------------------------------------------------
374
375    class thread_error : public error
376    {
377    public:
378        thread_error(
379            error_type t,
380            const std::string& a
381        ): error(t,a) {}
382        /*!
383            ensures
384                - #type == t
385                - #info == a
386        !*/
387
388        thread_error(
389            error_type t
390        ): error(t) {}
391        /*!
392            ensures
393                - #type == t
394                - #info == ""
395        !*/
396
397        thread_error(
398            const std::string& a
399        ): error(ETHREAD,a) {}
400        /*!
401            ensures
402                - #type == ETHREAD
403                - #info == a
404        !*/
405
406        thread_error(
407        ): error(ETHREAD) {}
408        /*!
409            ensures
410                - #type == ETHREAD
411                - #info == ""
412        !*/
413    };
414
415// ----------------------------------------------------------------------------------------
416
417}
418
419#endif // DLIB_ERROr_
420