From 93d83f045667a5bf620a8d17d1acc400f0b8e877 Mon Sep 17 00:00:00 2001
From: "Nicolas \"Pixel\" Noble" <pixel@nobis-crew.org>
Date: Wed, 16 Jan 2013 09:33:49 +0100
Subject: Since I have to eat these exceptions no matter what, let's try to
 improve them a bit for speed and efficiency.

---
 includes/Exceptions.h | 35 ++++++++++++++++++++---------------
 includes/Task.h       |  4 ++--
 2 files changed, 22 insertions(+), 17 deletions(-)

diff --git a/includes/Exceptions.h b/includes/Exceptions.h
index 5cdb232..103e394 100644
--- a/includes/Exceptions.h
+++ b/includes/Exceptions.h
@@ -8,24 +8,38 @@
 
 namespace Balau {
 
+class ClassName {
+  public:
+      template<typename T> ClassName(T * ptr);
+      ~ClassName() { free(m_demangled); }
+    const char * c_str() const { return m_demangled; }
+  private:
+    char * m_demangled;
+};
+
 class GeneralException {
   public:
-      GeneralException(const char * msg, const char * details = NULL, bool notrace = false) : m_msg(::strdup(msg)) { setDetails(details); if (!notrace) genTrace(); }
+      GeneralException(const char * msg, const char * details = NULL, bool notrace = false) : m_msg(msg ? ::strdup(msg) : NULL) { setDetails(details); if (!notrace) genTrace(); }
       GeneralException(const String & msg, const char * details = NULL, bool notrace = false) : m_msg(msg.strdup()) { setDetails(details); if (!notrace) genTrace(); }
-      GeneralException(const GeneralException & e) : m_msg(strdup(e.m_msg)), m_trace(e.m_trace) { setDetails(e.m_details); }
+      GeneralException(const GeneralException & e) : m_msg(e.m_msg ? strdup(e.m_msg) : NULL), m_trace(e.m_trace) { setDetails(e.m_details); }
       GeneralException(GeneralException && e) : m_msg(e.m_msg), m_trace(e.m_trace), m_details(e.m_details) { e.m_msg = e.m_details = NULL; }
-      ~GeneralException() { if (m_msg) free(m_msg); }
-    const char * getMsg() const { return m_msg; }
+      // don't hate me, this is to generate typeinfo in the getMsg() case where there's no message.
+      virtual ~GeneralException() { if (m_msg) free(m_msg); if (m_details) free(m_details); }
+    const char * getMsg() const {
+        if (!m_msg)
+            m_msg = ::strdup(ClassName(this).c_str());
+        return m_msg;
+    }
     const char * getDetails() const { return m_details; }
     const std::vector<String> getTrace() const { return m_trace; }
 
   protected:
-      GeneralException() : m_msg(0) { }
+      GeneralException() : m_msg(NULL), m_details(NULL) { }
     void setMsg(char * msg) { if (m_msg) free(m_msg); m_msg = msg; }
     void genTrace();
 
   private:
-    char * m_msg;
+    mutable char * m_msg;
     char * m_details;
     std::vector<String> m_trace;
 
@@ -99,15 +113,6 @@ static inline void TestHelper(const String & msg) throw (TestException) {
     throw TestException(msg);
 }
 
-class ClassName {
-  public:
-      template<typename T> ClassName(T * ptr);
-      ~ClassName() { free(m_demangled); }
-    const char * c_str() const { return m_demangled; }
-  private:
-    char * m_demangled;
-};
-
 template<typename T>
 ClassName::ClassName(T * ptr) {
     int status;
diff --git a/includes/Task.h b/includes/Task.h
index b7931e6..19e5262 100644
--- a/includes/Task.h
+++ b/includes/Task.h
@@ -15,7 +15,7 @@ namespace Events { class BaseEvent; };
 
 class EAgain : public GeneralException {
   public:
-      EAgain(Events::BaseEvent * evt) : GeneralException("Try Again", NULL, true), m_evt(evt) { }
+      EAgain(Events::BaseEvent * evt) : GeneralException(), m_evt(evt) { }
     Events::BaseEvent * getEvent() { return m_evt; }
   private:
     Events::BaseEvent * m_evt;
@@ -23,7 +23,7 @@ class EAgain : public GeneralException {
 
 class TaskSwitch : public GeneralException {
   public:
-      TaskSwitch() : GeneralException("Task Switch", NULL, true) { }
+      TaskSwitch() : GeneralException() { }
 };
 
 class TaskMan;
-- 
cgit v1.2.3