summaryrefslogtreecommitdiff
path: root/includes/Exceptions.h
blob: 05630907df19fe72d9f4698d981233fff2fcf3de (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#pragma once

#include <typeinfo>
#include <cxxabi.h>
#include <BString.h>

namespace Balau {

class GeneralException {
  public:
      GeneralException(const char * msg) : m_msg(::strdup(msg)) { }
      GeneralException(const String & msg) : m_msg(msg.strdup()) { }
      GeneralException(const GeneralException & e) : m_msg(strdup(e.m_msg)) { }
      ~GeneralException() { if (m_msg) free(m_msg); }
    const char * getMsg() const { return m_msg; }

  protected:
      GeneralException() : m_msg(0) { }
    void setMsg(char * msg) { if (m_msg) free(m_msg); m_msg = msg; }
  private:
    char * m_msg;
};

static inline void * malloc(size_t size) throw (GeneralException) {
    void * r = ::malloc(size);

    if (!r && size)
        throw GeneralException("Failed to allocate memory.");

    return r;
}

static inline void * calloc(size_t count, size_t size) throw (GeneralException) {
    void * r = ::calloc(count, size);

    if (!r && ((count * size) != 0))
        throw GeneralException("Failed to allocate memory.");

    return r;
}

static inline void * realloc(void * previous, size_t size) throw (GeneralException) {
    void * r = ::realloc(previous, size);

    if (!r && size)
        throw GeneralException("Failed to allocate memory.");

    return r;
}

static inline void AssertHelper(const String & msg) throw(GeneralException) { throw GeneralException(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;
    m_demangled = abi::__cxa_demangle(typeid(*ptr).name(), 0, 0, &status);
}

};

#define Assert(c) if (!(c)) { \
    Balau::String msg; \
    msg.set("Assertion " #c " failed at %s:%i", __FILE__, __LINE__); \
    Balau::AssertHelper(msg); \
}