CMake file

Update to C++ 11: std::shared_ptr, for each loops
Update to wxWidgets 3.0+
This commit is contained in:
Twan van Laarhoven
2020-04-08 00:18:14 +02:00
parent aa39a9bc71
commit 35a89676b4
53 changed files with 343 additions and 415 deletions
+4
View File
@@ -185,6 +185,10 @@ void handle_error(const Error& e) {
queue_message(e.is_fatal() ? MESSAGE_FATAL_ERROR : MESSAGE_ERROR, e.what());
}
void handle_error_now(const Error& e) {
queue_message(MESSAGE_FATAL_ERROR, e.what());
}
bool have_queued_message() {
wxMutexLocker lock(crit_error_handling);
return !message_queue.empty();
+3 -1
View File
@@ -156,6 +156,8 @@ enum MessageType
void queue_message(MessageType type, String const& msg);
/// Handle an error by queuing a message
void handle_error(const Error& e);
/// Handle an error by showing a message box
void handle_error_now(const Error& e);
/// Are there any queued messages?
bool have_queued_message();
@@ -170,7 +172,7 @@ String get_stack_trace();
/// Catch all types of errors, and pass then to handle_error
#define CATCH_ALL_ERRORS(handle_now) \
catch (const Error& e) { \
handle_error(e); \
if (handle_now) handle_error_now(e); else handle_error(e); \
} catch (const std::exception& e) { \
/* we don't throw std::exception ourselfs, so this is probably something serious */ \
String message(e.what(), IF_UNICODE(wxConvLocal, wxSTRING_MAXLEN) ); \
+20 -74
View File
@@ -18,77 +18,19 @@
// ----------------------------------------------------------------------------- : Typeof magic
#ifdef __GNUC__
// GCC has a buildin typeof function, so it doesn't need (as much) hacks
#define DECLARE_TYPEOF(T)
#define DECLARE_TYPEOF_NO_REV(T)
#define DECLARE_TYPEOF_CONST(T)
#define DECLARE_TYPEOF_COLLECTION(T)
#define TYPEOF(Value) __typeof(Value)
#define TYPEOF_IT(Value) __typeof((Value).begin())
#define TYPEOF_CIT(Value) __typeof((Value).begin())
#define TYPEOF_RIT(Value) __typeof((Value).rbegin())
#define TYPEOF_CRIT(Value) __typeof((Value).rbegin())
#define TYPEOF_REF(Value) __typeof(*(Value).begin())&
#define TYPEOF_CREF(Value) __typeof(*(Value).begin())&
#else
/// Helper for typeof tricks
template<const type_info &ref_type_info> struct TypeOf {};
// GCC has a buildin typeof function, so it doesn't need (as much) hacks
#define DECLARE_TYPEOF(T)
#define DECLARE_TYPEOF_NO_REV(T)
#define DECLARE_TYPEOF_CONST(T)
#define DECLARE_TYPEOF_COLLECTION(T)
/// The type of a value
#define TYPEOF(Value) TypeOf<typeid(Value)>::type
/// The type of an iterator
#define TYPEOF_IT(Value) TypeOf<typeid(Value)>::iterator
/// The type of a const iterator
#define TYPEOF_CIT(Value) TypeOf<typeid(Value)>::const_iterator
/// The type of a reverse iterator
#define TYPEOF_RIT(Value) TypeOf<typeid(Value)>::reverse_iterator
/// The type of a const reverse iterator
#define TYPEOF_CRIT(Value) TypeOf<typeid(Value)>::const_reverse_iterator
/// The type of a reference
#define TYPEOF_REF(Value) TypeOf<typeid(Value)>::reference
/// The type of a const reference
#define TYPEOF_CREF(Value) TypeOf<typeid(Value)>::const_reference
/// Declare typeof magic for a specific type
#define DECLARE_TYPEOF(T) \
template<> struct TypeOf<typeid(T)> { \
typedef T type; \
typedef T::iterator iterator; \
typedef T::const_iterator const_iterator; \
typedef T::reverse_iterator reverse_iterator; \
typedef T::const_reverse_iterator const_reverse_iterator; \
typedef T::reference reference; \
typedef T::const_reference const_reference; \
}
/// Declare typeof magic for a specific type that doesn't support reverse iterators
#define DECLARE_TYPEOF_NO_REV(T) \
template<> struct TypeOf<typeid(T)> { \
typedef T type; \
typedef T::iterator iterator; \
typedef T::const_iterator const_iterator; \
typedef T::reference reference; \
typedef T::const_reference const_reference; \
}
/// Declare typeof magic for a specific type, using const iterators
#define DECLARE_TYPEOF_CONST(T) \
template<> struct TypeOf<typeid(T)> { \
typedef T type; \
typedef T::const_iterator iterator; \
typedef T::const_iterator const_iterator; \
typedef T::const_reverse_iterator reverse_iterator; \
typedef T::const_reverse_iterator const_reverse_iterator; \
typedef T::const_reference reference; \
typedef T::const_reference const_reference; \
}
/// Declare typeof magic for a specific std::vector type
#define DECLARE_TYPEOF_COLLECTION(T) DECLARE_TYPEOF(vector< T >); \
DECLARE_TYPEOF_CONST(set< T >)
#endif
#define TYPEOF(Value) decltype(Value)
#define TYPEOF_IT(Value) decltype((Value).begin())
#define TYPEOF_CIT(Value) decltype((Value).begin())
#define TYPEOF_RIT(Value) decltype((Value).rbegin())
#define TYPEOF_CRIT(Value) decltype((Value).rbegin())
#define TYPEOF_REF(Value) decltype(*(Value).begin())&
#define TYPEOF_CREF(Value) decltype(*(Value).begin())&
/// Use for template classes
/** i.e.
@@ -151,15 +93,19 @@
/// Iterate over a collection whos type must be declared with DECLARE_TYPEOF
/** Usage: FOR_EACH(e,collect) { body-of-loop }
*/
#define FOR_EACH(Elem,Collection) \
FOR_EACH_T(TYPEOF_IT(Collection), TYPEOF_REF(Collection), Elem, Collection, begin, end)
//#define FOR_EACH(Elem,Collection) \
// FOR_EACH_T(TYPEOF_IT(Collection), TYPEOF_REF(Collection), Elem, Collection, begin, end)
#define FOR_EACH(Elem,Collection) \
for (auto& Elem : Collection)
/// Iterate over a collection whos type must be declared with DECLARE_TYPEOF
/** Uses a const iterator
* Usage: FOR_EACH_CONST(e,collect) { body-of-loop }
*/
#define FOR_EACH_CONST(Elem,Collection) \
FOR_EACH_T(TYPEOF_CIT(Collection), TYPEOF_CREF(Collection), Elem, Collection, begin, end)
//#define FOR_EACH_CONST(Elem,Collection) \
// FOR_EACH_T(TYPEOF_CIT(Collection), TYPEOF_CREF(Collection), Elem, Collection, begin, end)
#define FOR_EACH_CONST(Elem,Collection) \
for (auto const& Elem : Collection)
/// Iterate over a collection whos type must be declared with DECLARE_TYPEOF
/** Iterates using a reverse_iterator
+1 -14
View File
@@ -154,17 +154,8 @@ void Package::clearKeepFlag() {
// ----------------------------------------------------------------------------- : Package : inside
#if 0
/// Class that is a wxZipInputStream over a wxFileInput stream
/** Note that wxFileInputStream is also a base class, because it must be constructed first
* This class requires a patch in wxWidgets (2.5.4)
* change zipstrm.cpp line 1745:;
* if ((!m_ffile || AtHeader()));
* to:
* if ((AtHeader()));
* It seems that in 2.6.3 this is no longer necessary (TODO: test)
*
* NOTE: Not used with wx 2.6.3, since it doesn't support seeking
*/
class ZipFileInputStream : private wxFileInputStream, public wxZipInputStream {
public:
@@ -175,7 +166,6 @@ class ZipFileInputStream : private wxFileInputStream, public wxZipInputStream {
OpenEntry(*entry);
}
};
#endif
class BufferedFileInputStream_aux {
protected:
@@ -219,10 +209,7 @@ InputStreamP Package::openIn(const String& file) {
stream = shared(new BufferedFileInputStream(filename+_("/")+file));
} else if (wxFileExists(filename) && it != files.end() && it->second.zipEntry) {
// a file in a zip archive
// somebody in wx thought seeking was no longer needed, it now only works with the 'compatability constructor'
stream = shared(new wxZipInputStream(filename, it->second.zipEntry->GetInternalName()));
//stream = static_pointer_cast<wxZipInputStream>(
// shared(new ZipFileInputStream(filename, it->second.zipEntry)));
stream = static_pointer_cast<wxZipInputStream>(shared(new ZipFileInputStream(filename, it->second.zipEntry)));
} else {
// shouldn't happen, packaged changed by someone else since opening it
throw FileNotFoundError(file, filename);
+1 -1
View File
@@ -147,7 +147,7 @@ class Package : public IntrusivePtrVirtualBase {
protected:
// TODO: I dislike putting this here very much. There ought to be a better way.
virtual VCSP getVCS() { return intrusive(new VCS()); }
virtual VCSP getVCS() { return make_shared<VCS>(); }
/// true if this is a zip file, false if a directory
bool isZipfile() const { return !wxDirExists(filename); }
+3 -1
View File
@@ -402,7 +402,9 @@ template <> void Reader::handle(tribool& tb) {
// ----------------------------------------------------------------------------- : Handling less basic util types
template <> void Reader::handle(wxDateTime& date) {
if (!date.ParseDateTime(getValue().c_str())) {
auto str = getValue();
String::const_iterator end;
if (!date.ParseDateTime(str,&end) || end != str.end()) {
throw ParseError(_("Expected a date and time"));
}
}
+1 -1
View File
@@ -209,7 +209,7 @@ template <typename T> void update_index(T&, size_t index) {}
template <typename T>
void Reader::handle(const Char* name, vector<T>& vector) {
String vectorKey = singular_form(name);
while (enterBlock(vectorKey)) {
while (enterBlock(vectorKey.c_str())) {
vector.resize(vector.size() + 1);
handle_greedy(vector.back());
update_index(vector.back(), vector.size() - 1); // update index for IndexMap
+2 -1
View File
@@ -103,8 +103,9 @@ class Writer {
template <typename T>
void Writer::handle(const Char* name, const vector<T>& vec) {
String vectorKey = singular_form(name);
const Char* vectorKeyC = IF_UNICODE(vectorKey.wc_str(), vectorKey.c_str());
for (typename vector<T>::const_iterator it = vec.begin() ; it != vec.end() ; ++it) {
handle(vectorKey, *it);
handle(vectorKeyC, *it);
}
}
+2 -4
View File
@@ -19,6 +19,7 @@
# pragma warning (disable: 4355) // 'this' : used in base member initializer list
# pragma warning (disable: 4800) // 'int' : forcing value to bool 'true' or 'false' (performance warning)
# pragma warning (disable: 4675) // resolved overload was found by argument-dependent lookup (occurs in some boost header)
# define _CRT_NO_VA_START_VALIDATION // fix "va_start argument must not have reference type and must not be parenthesized"
#endif
// ----------------------------------------------------------------------------- : Includes
@@ -31,7 +32,7 @@
#include <wx/datetime.h>
#include <wx/regex.h> // TODO : remove, see regex.hpp
#if defined(__WXMSW__) && defined(__GNUC__)
#if defined(__WXMSW__)
// MSW uses the RGB define, fix it before it's undefined
#include <wx/msw/private.h>
#endif
@@ -87,9 +88,6 @@ typedef wxOutputStream OutputStream;
typedef unsigned char Byte;
typedef unsigned int UInt;
/// Null pointer
#define nullptr 0
/// A string standing for a filename, has different behaviour when reading/writing
class FileName : public wxString {
public:
+68 -68
View File
@@ -23,32 +23,32 @@
/// Declare that a class supports reflection
/** Reflection allows the member variables of a class to be inspected at runtime.
*/
#define DECLARE_REFLECTION() \
protected: \
template<class Tag> void reflect_impl(Tag& tag); \
friend class Reader; \
friend class Writer; \
friend class GetDefaultMember; \
friend class GetMember; \
void reflect(Reader& reader); \
void reflect(Writer& writer); \
void reflect(GetDefaultMember& gdm); \
void reflect(GetMember& gm)
#define DECLARE_REFLECTION() \
protected: \
template<class Tag> void reflect_impl(Tag& tag); \
friend class Reader; \
friend class Writer; \
friend class GetDefaultMember; \
friend class GetMember; \
void reflect(Reader& reader); \
void reflect(Writer& writer); \
void reflect(GetDefaultMember& gdm); \
void reflect(GetMember& gm)
/// Declare that a class supports reflection, which can be overridden in derived classes
#define DECLARE_REFLECTION_VIRTUAL() \
protected: \
template<class Tag> void reflect_impl(Tag& tag); \
friend class Reader; \
friend class Writer; \
friend class GetDefaultMember; \
friend class GetMember; \
/* extra level of indirection between Tag::handle \
* and reflect_impl, to allow for virtual */ \
virtual void reflect(Reader& reader); \
virtual void reflect(Writer& writer); \
virtual void reflect(GetDefaultMember& gdm); \
virtual void reflect(GetMember& gm)
#define DECLARE_REFLECTION_VIRTUAL() \
protected: \
template<class Tag> void reflect_impl(Tag& tag); \
friend class Reader; \
friend class Writer; \
friend class GetDefaultMember; \
friend class GetMember; \
/* extra level of indirection between Tag::handle \
* and reflect_impl, to allow for virtual */ \
virtual void reflect(Reader& reader); \
virtual void reflect(Writer& writer); \
virtual void reflect(GetDefaultMember& gdm); \
virtual void reflect(GetMember& gm)
// ----------------------------------------------------------------------------- : Implementing reflection
@@ -67,40 +67,40 @@
* }
* @endcode
*/
#define IMPLEMENT_REFLECTION(Cls) \
REFLECT_OBJECT_READER(Cls) \
REFLECT_OBJECT_WRITER(Cls) \
REFLECT_OBJECT_GET_DEFAULT_MEMBER_NOT(Cls) \
REFLECT_OBJECT_GET_MEMBER(Cls) \
template <class Tag> \
void Cls::reflect_impl(Tag& tag)
#define IMPLEMENT_REFLECTION(Cls) \
REFLECT_OBJECT_READER(Cls) \
REFLECT_OBJECT_WRITER(Cls) \
REFLECT_OBJECT_GET_DEFAULT_MEMBER_NOT(Cls) \
REFLECT_OBJECT_GET_MEMBER(Cls) \
template <class Tag> \
void Cls::reflect_impl(Tag& tag)
/// Implement the refelection of a class type Cls that only uses REFLECT_NAMELESS
#define IMPLEMENT_REFLECTION_NAMELESS(Cls) \
REFLECT_OBJECT_READER(Cls) \
REFLECT_OBJECT_WRITER(Cls) \
REFLECT_OBJECT_GET_DEFAULT_MEMBER(Cls) \
REFLECT_OBJECT_GET_MEMBER_NOT(Cls) \
template <class Tag> \
void Cls::reflect_impl(Tag& tag)
#define IMPLEMENT_REFLECTION_NAMELESS(Cls) \
REFLECT_OBJECT_READER(Cls) \
REFLECT_OBJECT_WRITER(Cls) \
REFLECT_OBJECT_GET_DEFAULT_MEMBER(Cls) \
REFLECT_OBJECT_GET_MEMBER_NOT(Cls) \
template <class Tag> \
void Cls::reflect_impl(Tag& tag)
/// Implement the refelection of a class type Cls, but only for Reader and Writer,
/** There is custom code for GetMember and GetDefaultMember */
#define IMPLEMENT_REFLECTION_NO_GET_MEMBER(Cls) \
REFLECT_OBJECT_READER(Cls) \
REFLECT_OBJECT_WRITER(Cls) \
template <class Tag> \
void Cls::reflect_impl(Tag& tag)
#define IMPLEMENT_REFLECTION_NO_GET_MEMBER(Cls) \
REFLECT_OBJECT_READER(Cls) \
REFLECT_OBJECT_WRITER(Cls) \
template <class Tag> \
void Cls::reflect_impl(Tag& tag)
/// Implement the refelection of a class type Cls, but only for Reader and Writer
/** There is no code for GetMember and GetDefaultMember */
#define IMPLEMENT_REFLECTION_NO_SCRIPT(Cls) \
REFLECT_OBJECT_READER(Cls) \
REFLECT_OBJECT_WRITER(Cls) \
REFLECT_OBJECT_GET_DEFAULT_MEMBER_NOT(Cls) \
REFLECT_OBJECT_GET_MEMBER_NOT(Cls) \
template <class Tag> \
void Cls::reflect_impl(Tag& tag)
#define IMPLEMENT_REFLECTION_NO_SCRIPT(Cls) \
REFLECT_OBJECT_READER(Cls) \
REFLECT_OBJECT_WRITER(Cls) \
REFLECT_OBJECT_GET_DEFAULT_MEMBER_NOT(Cls) \
REFLECT_OBJECT_GET_MEMBER_NOT(Cls) \
template <class Tag> \
void Cls::reflect_impl(Tag& tag)
/// Reflect a variable
#define REFLECT(var) tag.handle(_(#var), var)
@@ -150,15 +150,15 @@
#define REFLECT_NO_SCRIPT_N(name, var) tag.handleNoScript(_(name), var)
/// Explicitly instantiate reflection; this is occasionally required.
#define INSTANTIATE_REFLECTION(Class) \
template void Class::reflect_impl<Reader> (Reader&); \
template void Class::reflect_impl<Writer> (Writer&); \
template void Class::reflect_impl<GetMember> (GetMember&);
#define INSTANTIATE_REFLECTION(Class) \
template void Class::reflect_impl<Reader> (Reader&); \
template void Class::reflect_impl<Writer> (Writer&); \
template void Class::reflect_impl<GetMember> (GetMember&);
#define INSTANTIATE_REFLECTION_NAMELESS(Class) \
template void Class::reflect_impl<Reader> (Reader&); \
template void Class::reflect_impl<Writer> (Writer&); \
template void Class::reflect_impl<GetDefaultMember> (GetDefaultMember&);
#define INSTANTIATE_REFLECTION_NAMELESS(Class) \
template void Class::reflect_impl<Reader> (Reader&); \
template void Class::reflect_impl<Writer> (Writer&); \
template void Class::reflect_impl<GetDefaultMember> (GetDefaultMember&);
// ----------------------------------------------------------------------------- : Reflecting enums
@@ -178,20 +178,20 @@
* - Writer::handle(const Enum&)
* - GetDefaultMember::handle(const Enum&)
*/
#define IMPLEMENT_REFLECTION_ENUM(Enum) \
template <class Tag> \
void reflect_ ## Enum (Enum& enum_, Tag& tag); \
REFLECT_ENUM_READER(Enum) \
REFLECT_ENUM_WRITER(Enum) \
REFLECT_ENUM_GET_MEMBER(Enum) \
template <class Tag> \
void reflect_ ## Enum (Enum& enum_, Tag& tag)
#define IMPLEMENT_REFLECTION_ENUM(Enum) \
template <class Tag> \
void reflect_ ## Enum (Enum& enum_, Tag& tag); \
REFLECT_ENUM_READER(Enum) \
REFLECT_ENUM_WRITER(Enum) \
REFLECT_ENUM_GET_MEMBER(Enum) \
template <class Tag> \
void reflect_ ## Enum (Enum& enum_, Tag& tag)
/// Declare a possible value of an enum
#define VALUE(val) tag.handle(_(#val), val, enum_)
#define VALUE(val) tag.handle(_(#val), val, enum_)
/// Declare a possible value of an enum under the given name
#define VALUE_N(name, val) tag.handle(_(name), val, enum_)
#define VALUE_N(name, val) tag.handle(_(name), val, enum_)
// ----------------------------------------------------------------------------- : EOF
#endif
+4 -7
View File
@@ -16,7 +16,7 @@
void Regex::assign(const String& code) {
// compile string
try {
regex.assign(code.begin(),code.end());
regex.assign(toStdString(code));
} catch (const boost::regex_error& e) {
/// TODO: be more precise
throw ScriptError(String::Format(_("Error while compiling regular expression: '%s'\nAt position: %d\n%s"),
@@ -25,12 +25,9 @@ void Regex::assign(const String& code) {
}
void Regex::replace_all(String* input, const String& format) {
//std::basic_string<Char> fmt; format_string(format,fmt);
std::basic_string<Char> fmt(format.begin(),format.end());
String output;
regex_replace(insert_iterator<String>(output, output.end()),
input->begin(), input->end(), regex, fmt, boost::format_sed);
*input = output;
wxStdString std_string = toStdString(*input);
regex_replace(std_string, regex, toStdString(format), boost::format_sed);
*input = std_string;
}
#else // USE_BOOST_REGEX
+19 -1
View File
@@ -32,6 +32,24 @@
// ----------------------------------------------------------------------------- : Boost implementation
#if USE_BOOST_REGEX
// needed for boost::regex
inline std::size_t hash_value(wxUniChar const& x) {
boost::hash<int> hasher;
return hasher(static_cast<int>(x));
}
/*
// fix: boost regex doesn't like that wxUniChar can't be constructed from an int
namespace boost {
namespace BOOST_REGEX_DETAIL_NS {
inline bool can_start(wxUniChar c, const unsigned char* map, unsigned char mask) {
return can_start(c.GetValue(), map, mask);
}
inline bool can_start(wxUniCharRef c, const unsigned char* map, unsigned char mask) {
return can_start(c.GetValue(), map, mask);
}
}
}*/
/// Our own regular expression wrapper
/** Suppors both boost::regex and wxRegEx.
* Has an interface like boost::regex, but compatible with wxStrings.
@@ -59,7 +77,7 @@
void assign(const String& code);
inline bool matches(const String& str) const {
return regex_search(str.begin(), str.end(), regex);
return regex_search(toStdString(str), regex);
}
inline bool matches(Results& results, const String& str, size_t start = 0) const {
return matches(results, str.begin() + start, str.end());
+33 -125
View File
@@ -14,39 +14,22 @@
// ----------------------------------------------------------------------------- : Includes
#include <util/atomic.hpp>
#ifdef HAVE_FAST_ATOMIC
/// Using intrusive_ptr where possible? (as opposed to smart_ptr)
#define USE_INTRUSIVE_PTR
#endif
#include <memory>
// Use slightly less fancy template stuff, so msvc7.1 doesn't crash with an internal compiler error
#define BOOST_SP_NO_SP_CONVERTIBLE
using std::shared_ptr;
using std::unique_ptr;
using std::static_pointer_cast;
using std::dynamic_pointer_cast;
using std::make_shared;
#include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp>
#ifdef USE_INTRUSIVE_PTR
#include <boost/intrusive_ptr.hpp>
#endif
// Can't do using namespace boost;
// because boost::shared_ptr conflicts with std::tr1::shared_ptr
// and some boost headers do include boost/shared_ptr themselves
#if _HAS_TR1
using std::tr1::shared_ptr;
#else
using boost::shared_ptr;
#endif
using boost::intrusive_ptr;
using boost::scoped_ptr;
using boost::static_pointer_cast;
using boost::dynamic_pointer_cast;
// TODO: remove scoped_ptr
template <typename T> using scoped_ptr = unique_ptr<T>;
// ----------------------------------------------------------------------------- : Declaring
/// Declares the type TypeP as a shared_ptr<Type>
#define DECLARE_SHARED_POINTER_TYPE(Type) \
class Type; \
#define DECLARE_SHARED_POINTER_TYPE(Type) \
class Type; \
typedef shared_ptr<Type> Type##P;
// ----------------------------------------------------------------------------- : Creating
@@ -56,113 +39,38 @@ using boost::dynamic_pointer_cast;
* return shared(new T(stuff)));
*/
template <typename T>
//[[deprecated("use make_shared")]]
inline shared_ptr<T> shared(T* ptr) {
return shared_ptr<T>(ptr);
}
template <typename T>
//[[deprecated("use make_shared")]]
inline shared_ptr<T> intrusive(T* ptr) {
return shared_ptr<T>(ptr);
}
// ----------------------------------------------------------------------------- : Intrusive pointers
#ifdef USE_INTRUSIVE_PTR
#define DECLARE_POINTER_TYPE DECLARE_SHARED_POINTER_TYPE
#define intrusive_ptr shared_ptr
/// Declares the type TypeP as a intrusive_ptr<Type>
#define DECLARE_POINTER_TYPE(Type) \
class Type; \
typedef intrusive_ptr<Type> Type##P;
template <typename T> class IntrusivePtrBase {};
/// Wrap a newly allocated pointer in an intrusive_ptr
/** Usage:
* return intrusive(new T(stuff)));
*/
template <typename T>
inline intrusive_ptr<T> intrusive(T* ptr) {
return intrusive_ptr<T>(ptr);
/// IntrusivePtrBase with a virtual destructor
class IntrusivePtrVirtualBase : public IntrusivePtrBase<IntrusivePtrVirtualBase> {
public:
virtual ~IntrusivePtrVirtualBase() {}
};
class IntrusivePtrBaseWithDelete : public IntrusivePtrBase<IntrusivePtrBaseWithDelete> {
public:
virtual ~IntrusivePtrBaseWithDelete() {}
protected:
/// Delete this object
virtual void destroy() {
delete this;
}
// ----------------------------------------------------------------------------- : Intrusive pointer base
template <typename T> class IntrusivePtrBase;
template <typename T> void intrusive_ptr_add_ref(IntrusivePtrBase<T>*);
template <typename T> void intrusive_ptr_release(IntrusivePtrBase<T>*);
/// Base class for objects wishing to use intrusive_ptrs.
/** There is no implicit virtual destructor, objects are destructed as type T
* Usage:
* @code
* DECLARE_POINTER_TYPE(MyClass);
* class MyClass : public IntrusivePtrBase<MyClass> { ... }
* @endcode
*/
template <typename T> class IntrusivePtrBase {
public:
inline IntrusivePtrBase() : ref_count(0) {}
// don't copy construct the reference count!
inline IntrusivePtrBase(const IntrusivePtrBase&) : ref_count(0) {}
// don't assign the reference count!
inline void operator = (const IntrusivePtrBase&) { }
protected:
/// Delete this object, can be overloaded
inline void destroy() {
delete static_cast<T*>(this);
}
private:
AtomicInt ref_count;
friend void intrusive_ptr_add_ref <> (IntrusivePtrBase*);
friend void intrusive_ptr_release <> (IntrusivePtrBase*);
};
template <typename T> void intrusive_ptr_add_ref(IntrusivePtrBase<T>* p) {
++(p->ref_count);
}
template <typename T> void intrusive_ptr_release(IntrusivePtrBase<T>* p) {
if (--p->ref_count == 0) {
static_cast<T*>(p)->destroy();
}
}
// ----------------------------------------------------------------------------- : Intrusive pointer base : virtual
/// IntrusivePtrBase with a virtual destructor
class IntrusivePtrVirtualBase : public IntrusivePtrBase<IntrusivePtrVirtualBase> {
public:
virtual ~IntrusivePtrVirtualBase() {}
};
// ----------------------------------------------------------------------------- : Intrusive pointer base : with delete
/// Base class for objects wishing to use intrusive_ptrs, using a manual delete function
class IntrusivePtrBaseWithDelete : public IntrusivePtrBase<IntrusivePtrBaseWithDelete> {
public:
virtual ~IntrusivePtrBaseWithDelete() {}
protected:
/// Delete this object
virtual void destroy() {
delete this;
}
template <typename T> friend void intrusive_ptr_release(IntrusivePtrBase<T>*);
};
#else
#define DECLARE_POINTER_TYPE DECLARE_SHARED_POINTER_TYPE
#define intrusive_ptr shared_ptr
template <typename T> class IntrusivePtrBase {};
/// IntrusivePtrBase with a virtual destructor
class IntrusivePtrVirtualBase : public IntrusivePtrBase<IntrusivePtrVirtualBase> {
public:
virtual ~IntrusivePtrVirtualBase() {}
};
class IntrusivePtrBaseWithDelete : public IntrusivePtrBase<IntrusivePtrBaseWithDelete> {
public:
virtual ~IntrusivePtrBaseWithDelete() {}
protected:
/// Delete this object
virtual void destroy() {
delete this;
}
};
#endif
};
/// Pointer to 'anything'
typedef intrusive_ptr<IntrusivePtrVirtualBase> VoidP;
+11 -3
View File
@@ -28,6 +28,14 @@ typedef wxString String;
DECLARE_TYPEOF_NO_REV(String); // iterating over characters in a string
inline wxStdString const& toStdString(String const& s) {
#if wxUSE_UNICODE_WCHAR
return s.ToStdWstring();
#else
return s.ToStdString();
#endif
}
// ----------------------------------------------------------------------------- : Unicode
/// u if UNICODE is defined, a otherwise
@@ -42,8 +50,8 @@ DECLARE_TYPEOF_NO_REV(String); // iterating over characters in a string
#define _(S) IF_UNICODE(BOOST_PP_CAT(L,S), S)
/// The character type used
typedef IF_UNICODE(wchar_t, char) Char;
typedef wxChar Char;
/// Decode a UTF8 string
/** In non-unicode builds the input is considered to be an incorrectly encoded utf8 string.
* In unicode builds it is a normal string, utf8 already decoded.
@@ -55,7 +63,7 @@ String decodeUTF8BOM(const String& s);
/** In non-unicode builds it is UTF8 encoded \xFEFF.
* In unicode builds it is a normal \xFEFF.
*/
const Char BYTE_ORDER_MARK[] = IF_UNICODE(L"\xFEFF", "\xEF\xBB\xBF");
const Char BYTE_ORDER_MARK[] = L"\xFEFF";
/// Writes a string to an output stream, encoded as UTF8
void writeUTF8(wxTextOutputStream& stream, const String& str);