iLab Neuromorphic Robotics Toolkit  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Exception.H
Go to the documentation of this file.
1 /*! @file
2  @author Laurent Itti
3  @copyright GNU Public License (GPL v3)
4  @section License
5  @verbatim
6  // ////////////////////////////////////////////////////////////////////////
7  // The iLab Neuromorphic Robotics Toolkit (NRT) //
8  // Copyright 2010-2012 by the University of Southern California (USC) //
9  // and the iLab at USC. //
10  // //
11  // iLab - University of Southern California //
12  // Hedco Neurociences Building, Room HNB-10 //
13  // Los Angeles, Ca 90089-2520 - USA //
14  // //
15  // See http://ilab.usc.edu for information about this project. //
16  // ////////////////////////////////////////////////////////////////////////
17  // This file is part of The iLab Neuromorphic Robotics Toolkit. //
18  // //
19  // The iLab Neuromorphic Robotics Toolkit is free software: you can //
20  // redistribute it and/or modify it under the terms of the GNU General //
21  // Public License as published by the Free Software Foundation, either //
22  // version 3 of the License, or (at your option) any later version. //
23  // //
24  // The iLab Neuromorphic Robotics Toolkit is distributed in the hope //
25  // that it will be useful, but WITHOUT ANY WARRANTY; without even the //
26  // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //
27  // PURPOSE. See the GNU General Public License for more details. //
28  // //
29  // You should have received a copy of the GNU General Public License //
30  // along with The iLab Neuromorphic Robotics Toolkit. If not, see //
31  // <http://www.gnu.org/licenses/>. //
32  // ////////////////////////////////////////////////////////////////////////
33  @endverbatim */
34 
35 #ifndef INCLUDE_NRT_CORE_TYPING_EXCEPTION_H
36 #define INCLUDE_NRT_CORE_TYPING_EXCEPTION_H
37 
38 #include <nrt/External/cereal/types/string.hpp>
39 #include <string>
40 #include <exception>
41 
42 //! Reserved namespace for NRT core classes and functions
43 namespace nrt
44 {
45  /*! \defgroup exceptions Exception base classes and helper functions
46  \ingroup typing */
47 
48  /*! @{ */ // **********************************************************************
49 
50  //! Convenience function to catch an exception, issue some NRT_WARNING (depending on type), and rethrow it
51  /*! User code that is not going to swallow exceptions can use this function as follows, to log some trace of the
52  exception that was thrown:
53 
54  \code
55  try { do_something_risky(); } catch (...) { nrt::warnAndRethrowException(); }
56  \endcode
57 
58  \note This function throws! So obviously it only makes sense to use it inside a catch block. */
60 
61  //! Convenience function to catch an exception, issue some NRT_WARNING (depending on type), and ignore it
62  /*! User code can use this function as follows, to log some trace of the exception that was thrown, and then swallow
63  (ignore) the exception. Use this sparingly, swallowing exceptions often defeats the whole logic of using
64  exceptions in the first place. Example use:
65 
66  \code
67  try { do_something_risky_and_we_dont_care_if_it_fails(); } catch (...) { nrt::warnAndIgnoreException(); }
68  \endcode */
70 
71  //! Reserved namespace for NRT-related exceptions
72  namespace exception
73  {
74  // ######################################################################
75  //! Exception base class for NRT. This is essentially the same as std::exception but in the nrt namespace
76  /*! It is tricky to ensure that constructor, destructor, and what() functions of derived exceptions won't throw. The
77  recommended definition of a derived exception is as follows:
78 
79  @code
80  class MyException : public nrt::exception::Exception
81  {
82  public:
83  MyException(std::string const & msg, int const some_value) throw()
84  : nrt::exception::Exception("Error MyException, and further error while constructing the exception")
85  {
86  try {
87  // Do things that could throw:
88  std::ostringstream os;
89  os << "Error MyException with message [" << msg << "] and value [" << some_value;
90  whatstring = os.str();
91 
92  // At last set whatptr when you know nothing will throw anymore:
93  whatptr = whatstring.c_str();
94  }
95  catch (...) { } // oops, failed assembling error message, the one specified in the initializer
96  // list will then be used. Here we don't throw.
97  }
98 
99  virtual ~MyException() { }
100 
101  private:
102  std::string whatstring;
103  };
104  @endcode
105 
106  If you want a more complicated initializer list, then use this fancy syntax for your constructor:
107  @code
108  MyException(std::string const & msg, ComplexObject const & obj) throw()
109  try : nrt::exception::Exception("Error MyException, and further error while constructing the exception"),
110  myobj(obj)
111  {
112  // possibly fiddle more with msg, myobj, etc and create a whatstring data member
113 
114  // At last set whatptr when you know nothing will throw anymore:
115  whatptr = whatstring.c_str();
116  }
117  catch (...) { } // nrt::Exception::Exception() does not throw, so here just cleanup your other objects
118  @endcode
119 
120  See here for more info: http://www.gotw.ca/gotw/066.htm */
121  class Exception : public std::exception
122  {
123  public:
124  //! Constructor with a default non-specific error message
125  Exception() throw();
126 
127  //! Constructor with a given error message
128  /*! The message is given as an old-school C string to ensure that the exception constructor won't throw. In the
129  constructor we just set whatptr to that C string. Typically that string would be a plain string message in
130  your code (i.e., not dynamically allocated, temporary object, etc). */
131  Exception(char const * msg) throw();
132 
133  //! Copy constructor
134  Exception(Exception const & e) throw();
135 
136  //! Virtual destructor for safe inheritance
137  virtual ~Exception() throw();
138 
139  //! Assignment
140  Exception & operator=(Exception const & e) throw();
141 
142  //! Return a C string describing the error
143  /*! In derived classes, do not overload what(), but instead just set whatptr to point to your error message. */
144  char const * what() const throw();
145 
146  protected:
147  //! Pointer to a message, returned by what()
148  char const * whatptr;
149  };
150 
151  // ######################################################################
152  //! Base class for a serializable exception. Anything that derives from this must implement serialize()
154  {
155  public:
156  //! Default constructor
157  SerializableException() throw();
158 
159  //! Construct from a C string message
160  SerializableException(char const * msg) throw();
161 
162  //! Copy constructor
163  SerializableException(SerializableException const & e) throw();
164 
165  //! Destructor
166  virtual ~SerializableException() throw();
167 
168  //! Assignment
170 
171  protected:
172  friend class cereal::access;
173 
174  //! The string representing the exception message
175  std::string whatstring;
176 
177  //! Serialization
178  template <class Archive> void serialize(Archive & ar)
179  { ar(whatstring); whatptr = whatstring.c_str(); }
180  };
181 
182  /*! @} */ // **********************************************************************
183 
184  } // namespace exception
185 } // namespace nrt
186 
187 #endif // INCLUDE_NRT_CORE_TYPING_EXCEPTION_H