mirror of
https://github.com/id-Software/GtkRadiant.git
synced 2026-03-19 16:39:26 +01:00
The GtkRadiant sources as originally released under the GPL license.
This commit is contained in:
23
libs/generic/arrayrange.cpp
Normal file
23
libs/generic/arrayrange.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
Copyright (C) 2001-2006, William Joseph.
|
||||
All Rights Reserved.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GtkRadiant is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "arrayrange.h"
|
||||
|
||||
72
libs/generic/arrayrange.h
Normal file
72
libs/generic/arrayrange.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
Copyright (C) 2001-2006, William Joseph.
|
||||
All Rights Reserved.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GtkRadiant is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if !defined(INCLUDED_GENERIC_ARRAYRANGE_H)
|
||||
#define INCLUDED_GENERIC_ARRAYRANGE_H
|
||||
|
||||
/// \file
|
||||
/// \brief Macros for automatically converting a compile-time-sized array to a range.
|
||||
|
||||
template<typename Element>
|
||||
struct ArrayRange
|
||||
{
|
||||
typedef Element* Iterator;
|
||||
ArrayRange(Iterator _begin, Iterator _end)
|
||||
: begin(_begin), end(_end)
|
||||
{
|
||||
}
|
||||
Iterator begin;
|
||||
Iterator end;
|
||||
};
|
||||
|
||||
template<typename Element>
|
||||
inline ArrayRange<Element> makeArrayRange(Element* begin, Element* end)
|
||||
{
|
||||
return ArrayRange<Element>(begin, end);
|
||||
}
|
||||
|
||||
template<typename Element>
|
||||
struct ArrayConstRange
|
||||
{
|
||||
typedef const Element* Iterator;
|
||||
ArrayConstRange(Iterator _begin, Iterator _end)
|
||||
: begin(_begin), end(_end)
|
||||
{
|
||||
}
|
||||
Iterator begin;
|
||||
Iterator end;
|
||||
};
|
||||
|
||||
template<typename Element>
|
||||
inline ArrayConstRange<Element> makeArrayRange(const Element* begin, const Element* end)
|
||||
{
|
||||
return ArrayConstRange<Element>(begin, end);
|
||||
}
|
||||
|
||||
#define ARRAY_SIZE(array) (sizeof(array) / sizeof(*array))
|
||||
#define ARRAY_END(array) (array + ARRAY_SIZE(array))
|
||||
#define ARRAY_RANGE(array) (makeArrayRange(array, ARRAY_END(array)))
|
||||
|
||||
|
||||
typedef ArrayConstRange<const char*> StringArrayRange;
|
||||
#define STRING_ARRAY_RANGE(array) (StringArrayRange(array, ARRAY_END(array)))
|
||||
|
||||
#endif
|
||||
23
libs/generic/bitfield.cpp
Normal file
23
libs/generic/bitfield.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
Copyright (C) 2001-2006, William Joseph.
|
||||
All Rights Reserved.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GtkRadiant is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "bitfield.h"
|
||||
|
||||
133
libs/generic/bitfield.h
Normal file
133
libs/generic/bitfield.h
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
Copyright (C) 2001-2006, William Joseph.
|
||||
All Rights Reserved.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GtkRadiant is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if !defined(INCLUDED_GENERIC_BITFIELD_H)
|
||||
#define INCLUDED_GENERIC_BITFIELD_H
|
||||
|
||||
/// \file
|
||||
/// \brief Type safe bitfield.
|
||||
|
||||
/// \brief A bit-field value.
|
||||
///
|
||||
/// - Can be forward-declared when the definition of Enumeration is unknown.
|
||||
/// - Can only be constructed from valid enumerated values.
|
||||
/// - Can only be compared and combined with others of the same type.
|
||||
///
|
||||
/// \param Enumeration A type that contains an enum \c Value of the bits that can be set in this field.
|
||||
template<typename Enumeration>
|
||||
class BitFieldValue : public Enumeration
|
||||
{
|
||||
unsigned m_value;
|
||||
protected:
|
||||
explicit BitFieldValue(unsigned value) : m_value(value)
|
||||
{
|
||||
}
|
||||
public:
|
||||
BitFieldValue() : m_value(0)
|
||||
{
|
||||
}
|
||||
explicit BitFieldValue(typename Enumeration::Value value) : m_value(1 << value)
|
||||
{
|
||||
}
|
||||
unsigned get() const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Enumeration>
|
||||
class BitFieldValueUnsafe : public BitFieldValue<Enumeration>
|
||||
{
|
||||
public:
|
||||
explicit BitFieldValueUnsafe(unsigned value) : BitFieldValue<Enumeration>(value)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Enumeration>
|
||||
inline bool operator==(BitFieldValue<Enumeration> self, BitFieldValue<Enumeration> other)
|
||||
{
|
||||
return self.get() == other.get();
|
||||
}
|
||||
template<typename Enumeration>
|
||||
inline bool operator!=(BitFieldValue<Enumeration> self, BitFieldValue<Enumeration> other)
|
||||
{
|
||||
return !operator==(self, other);
|
||||
}
|
||||
|
||||
template<typename Enumeration>
|
||||
inline BitFieldValue<Enumeration> operator|(BitFieldValue<Enumeration> self, BitFieldValue<Enumeration> other)
|
||||
{
|
||||
return BitFieldValueUnsafe<Enumeration>(self.get() | other.get());
|
||||
}
|
||||
template<typename Enumeration>
|
||||
inline BitFieldValue<Enumeration>& operator|=(BitFieldValue<Enumeration>& self, BitFieldValue<Enumeration> other)
|
||||
{
|
||||
return self = self | other;
|
||||
}
|
||||
template<typename Enumeration>
|
||||
inline BitFieldValue<Enumeration> operator&(BitFieldValue<Enumeration> self, BitFieldValue<Enumeration> other)
|
||||
{
|
||||
return BitFieldValueUnsafe<Enumeration>(self.get() & other.get());
|
||||
}
|
||||
template<typename Enumeration>
|
||||
inline BitFieldValue<Enumeration>& operator&=(BitFieldValue<Enumeration>& self, BitFieldValue<Enumeration> other)
|
||||
{
|
||||
return self = self & other;
|
||||
}
|
||||
template<typename Enumeration>
|
||||
inline BitFieldValue<Enumeration> operator~(BitFieldValue<Enumeration> self)
|
||||
{
|
||||
return BitFieldValueUnsafe<Enumeration>(~self.get());
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline unsigned int bitfield_enable(unsigned int bitfield, unsigned int mask)
|
||||
{
|
||||
return bitfield | mask;
|
||||
}
|
||||
inline unsigned int bitfield_disable(unsigned int bitfield, unsigned int mask)
|
||||
{
|
||||
return bitfield & ~mask;
|
||||
}
|
||||
inline bool bitfield_enabled(unsigned int bitfield, unsigned int mask)
|
||||
{
|
||||
return (bitfield & mask) != 0;
|
||||
}
|
||||
|
||||
template<typename Enumeration>
|
||||
inline BitFieldValue<Enumeration> bitfield_enable(BitFieldValue<Enumeration> bitfield, BitFieldValue<Enumeration> mask)
|
||||
{
|
||||
return bitfield | mask;
|
||||
}
|
||||
template<typename Enumeration>
|
||||
inline BitFieldValue<Enumeration> bitfield_disable(BitFieldValue<Enumeration> bitfield, BitFieldValue<Enumeration> mask)
|
||||
{
|
||||
return bitfield & ~mask;
|
||||
}
|
||||
template<typename Enumeration>
|
||||
inline bool bitfield_enabled(BitFieldValue<Enumeration> bitfield, BitFieldValue<Enumeration> mask)
|
||||
{
|
||||
return (bitfield & mask).get() != 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
109
libs/generic/callback.cpp
Normal file
109
libs/generic/callback.cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
Copyright (C) 2001-2006, William Joseph.
|
||||
All Rights Reserved.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GtkRadiant is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "callback.h"
|
||||
|
||||
#if defined(_DEBUG) || defined(DOXYGEN)
|
||||
|
||||
namespace ExampleMemberCaller
|
||||
{
|
||||
// MemberCaller example
|
||||
class Integer
|
||||
{
|
||||
public:
|
||||
int value;
|
||||
|
||||
void printValue() const
|
||||
{
|
||||
// print this->value here;
|
||||
}
|
||||
|
||||
void setValue()
|
||||
{
|
||||
value = 3;
|
||||
}
|
||||
// a typedef to make things more readable
|
||||
typedef MemberCaller<Integer, &Integer::setValue> SetValueCaller;
|
||||
};
|
||||
|
||||
void example()
|
||||
{
|
||||
Integer foo = { 0 };
|
||||
|
||||
{
|
||||
Callback bar = ConstMemberCaller<Integer, &Integer::printValue>(foo);
|
||||
|
||||
// invoke the callback
|
||||
bar(); // foo.printValue()
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
// use the typedef to improve readability
|
||||
Callback bar = Integer::SetValueCaller(foo);
|
||||
|
||||
// invoke the callback
|
||||
bar(); // foo.setValue()
|
||||
}
|
||||
}
|
||||
// end example
|
||||
}
|
||||
|
||||
namespace ExampleReferenceCaller
|
||||
{
|
||||
// ReferenceCaller example
|
||||
void Int_printValue(const int& value)
|
||||
{
|
||||
// print value here;
|
||||
}
|
||||
|
||||
void Int_setValue(int& value)
|
||||
{
|
||||
value = 3;
|
||||
}
|
||||
|
||||
// a typedef to make things more readable
|
||||
typedef ReferenceCaller<int, Int_setValue> IntSetValueCaller;
|
||||
|
||||
void example()
|
||||
{
|
||||
int foo = 0;
|
||||
|
||||
{
|
||||
Callback bar = ConstReferenceCaller<int, Int_printValue>(foo);
|
||||
|
||||
// invoke the callback
|
||||
bar(); // Int_printValue(foo)
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
// use the typedef to improve readability
|
||||
Callback bar = IntSetValueCaller(foo);
|
||||
|
||||
// invoke the callback
|
||||
bar(); // Int_setValue(foo)
|
||||
}
|
||||
}
|
||||
// end example
|
||||
}
|
||||
|
||||
#endif
|
||||
537
libs/generic/callback.h
Normal file
537
libs/generic/callback.h
Normal file
@@ -0,0 +1,537 @@
|
||||
/*
|
||||
Copyright (C) 2001-2006, William Joseph.
|
||||
All Rights Reserved.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GtkRadiant is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if !defined(INCLUDED_GENERIC_CLOSURE_H)
|
||||
#define INCLUDED_GENERIC_CLOSURE_H
|
||||
|
||||
/// \file
|
||||
/// \brief Type-safe techniques for binding the first argument of an anonymous callback.
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
/// \brief Combines a void pointer with a pointer to a function which operates on a void pointer.
|
||||
///
|
||||
/// Use with the callback constructors MemberCaller, ConstMemberCaller, ReferenceCaller, ConstReferenceCaller, PointerCaller, ConstPointerCaller and FreeCaller.
|
||||
class Callback
|
||||
{
|
||||
typedef void (*Thunk)(void*);
|
||||
void* m_environment;
|
||||
Thunk m_thunk;
|
||||
|
||||
static void nullThunk(void*)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
Callback() : m_environment(0), m_thunk(nullThunk)
|
||||
{
|
||||
}
|
||||
Callback(void* environment, Thunk function) : m_environment(environment), m_thunk(function)
|
||||
{
|
||||
}
|
||||
void* getEnvironment() const
|
||||
{
|
||||
return m_environment;
|
||||
}
|
||||
Thunk getThunk() const
|
||||
{
|
||||
return m_thunk;
|
||||
}
|
||||
void operator()() const
|
||||
{
|
||||
m_thunk(m_environment);
|
||||
}
|
||||
};
|
||||
|
||||
inline bool operator==(const Callback& self, const Callback& other)
|
||||
{
|
||||
return self.getEnvironment() == other.getEnvironment() && self.getThunk() == other.getThunk();
|
||||
}
|
||||
inline bool operator<(const Callback& self, const Callback& other)
|
||||
{
|
||||
return self.getEnvironment() < other.getEnvironment() ||
|
||||
(!(other.getEnvironment() < self.getEnvironment()) && self.getThunk() < other.getThunk());
|
||||
}
|
||||
|
||||
/// \brief Combines a void pointer with a pointer to a function which operates on a void pointer and one other argument.
|
||||
///
|
||||
/// Use with the callback constructors MemberCaller1, ConstMemberCaller1, ReferenceCaller1, ConstReferenceCaller1, PointerCaller1, ConstPointerCaller1 and FreeCaller1.
|
||||
template<typename FirstArgument>
|
||||
class Callback1
|
||||
{
|
||||
typedef void (*Thunk)(void*, FirstArgument);
|
||||
void* m_environment;
|
||||
Thunk m_thunk;
|
||||
|
||||
static void nullThunk(void*, FirstArgument)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
typedef FirstArgument first_argument_type;
|
||||
|
||||
Callback1() : m_environment(0), m_thunk(nullThunk)
|
||||
{
|
||||
}
|
||||
Callback1(void* environment, Thunk function) : m_environment(environment), m_thunk(function)
|
||||
{
|
||||
}
|
||||
void* getEnvironment() const
|
||||
{
|
||||
return m_environment;
|
||||
}
|
||||
Thunk getThunk() const
|
||||
{
|
||||
return m_thunk;
|
||||
}
|
||||
void operator()(FirstArgument firstArgument) const
|
||||
{
|
||||
m_thunk(m_environment, firstArgument);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename FirstArgument>
|
||||
inline bool operator==(const Callback1<FirstArgument>& self, const Callback1<FirstArgument>& other)
|
||||
{
|
||||
return self.getEnvironment() == other.getEnvironment() && self.getThunk() == other.getThunk();
|
||||
}
|
||||
template<typename FirstArgument>
|
||||
inline bool operator<(const Callback1<FirstArgument>& self, const Callback1<FirstArgument>& other)
|
||||
{
|
||||
return self.getEnvironment() < other.getEnvironment() ||
|
||||
(!(other.getEnvironment() < self.getEnvironment()) && self.getThunk() < other.getThunk());
|
||||
}
|
||||
|
||||
template<typename Functor>
|
||||
class FunctorInvoke
|
||||
{
|
||||
public:
|
||||
inline void operator()(Functor functor)
|
||||
{
|
||||
functor();
|
||||
}
|
||||
};
|
||||
|
||||
typedef FunctorInvoke<Callback> CallbackInvoke;
|
||||
|
||||
|
||||
template<typename Functor, typename FirstArgument>
|
||||
class Functor1Invoke
|
||||
{
|
||||
FirstArgument m_firstArgument;
|
||||
public:
|
||||
Functor1Invoke(FirstArgument firstArgument) : m_firstArgument(firstArgument)
|
||||
{
|
||||
}
|
||||
inline void operator()(Functor functor)
|
||||
{
|
||||
functor(m_firstArgument);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
typedef Callback1<bool> BoolImportCallback;
|
||||
typedef Callback1<const BoolImportCallback&> BoolExportCallback;
|
||||
|
||||
typedef Callback1<int> IntImportCallback;
|
||||
typedef Callback1<const IntImportCallback&> IntExportCallback;
|
||||
|
||||
typedef Callback1<float> FloatImportCallback;
|
||||
typedef Callback1<const FloatImportCallback&> FloatExportCallback;
|
||||
|
||||
typedef Callback1<const char*> StringImportCallback;
|
||||
typedef Callback1<const StringImportCallback&> StringExportCallback;
|
||||
|
||||
typedef Callback1<std::size_t> SizeImportCallback;
|
||||
typedef Callback1<const SizeImportCallback&> SizeExportCallback;
|
||||
|
||||
|
||||
/// \brief Forms a Callback from a non-const Environment reference and a non-const Environment member-function.
|
||||
///
|
||||
/// \dontinclude generic/callback.cpp
|
||||
/// \skipline MemberCaller example
|
||||
/// \until end example
|
||||
template<typename Environment, void (Environment::*member)()>
|
||||
class MemberCaller
|
||||
{
|
||||
Environment& m_environment;
|
||||
public:
|
||||
MemberCaller(Environment& environment) : m_environment(environment)
|
||||
{
|
||||
}
|
||||
void* getEnvironment() const
|
||||
{
|
||||
return &m_environment;
|
||||
}
|
||||
static void thunk(void* environment)
|
||||
{
|
||||
((*reinterpret_cast<Environment*>(environment)).*member)();
|
||||
}
|
||||
operator Callback() const
|
||||
{
|
||||
return Callback(getEnvironment(), thunk);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Forms a Callback from a const Environment reference and a const Environment member-function.
|
||||
///
|
||||
/// \dontinclude generic/callback.cpp
|
||||
/// \skipline MemberCaller example
|
||||
/// \until end example
|
||||
template<typename Environment, void (Environment::*member)() const>
|
||||
class ConstMemberCaller
|
||||
{
|
||||
const Environment& m_environment;
|
||||
public:
|
||||
ConstMemberCaller(const Environment& environment) : m_environment(environment)
|
||||
{
|
||||
}
|
||||
void* getEnvironment() const
|
||||
{
|
||||
return const_cast<Environment*>(&m_environment);
|
||||
}
|
||||
static void thunk(void* environment)
|
||||
{
|
||||
((*reinterpret_cast<const Environment*>(environment)).*member)();
|
||||
}
|
||||
operator Callback() const
|
||||
{
|
||||
return Callback(getEnvironment(), thunk);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Forms a Callback from a non-const Environment reference and a const Environment member-function which takes one argument.
|
||||
template<typename Environment, typename FirstArgument, void (Environment::*member)(FirstArgument)>
|
||||
class MemberCaller1
|
||||
{
|
||||
Environment& m_environment;
|
||||
public:
|
||||
MemberCaller1(Environment& environment) : m_environment(environment)
|
||||
{
|
||||
}
|
||||
void* getEnvironment() const
|
||||
{
|
||||
return &m_environment;
|
||||
}
|
||||
static void thunk(void* environment, FirstArgument firstArgument)
|
||||
{
|
||||
((*reinterpret_cast<Environment*>(environment)).*member)(firstArgument);
|
||||
}
|
||||
operator Callback1<FirstArgument>() const
|
||||
{
|
||||
return Callback1<FirstArgument>(getEnvironment(), thunk);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Forms a Callback from a const Environment reference and a const Environment member-function which takes one argument.
|
||||
template<typename Environment, typename FirstArgument, void (Environment::*member)(FirstArgument) const>
|
||||
class ConstMemberCaller1
|
||||
{
|
||||
const Environment& m_environment;
|
||||
public:
|
||||
ConstMemberCaller1(const Environment& environment) : m_environment(environment)
|
||||
{
|
||||
}
|
||||
void* getEnvironment() const
|
||||
{
|
||||
return const_cast<Environment*>(&m_environment);
|
||||
}
|
||||
static void thunk(void* environment, FirstArgument firstArgument)
|
||||
{
|
||||
((*reinterpret_cast<Environment*>(environment)).*member)(firstArgument);
|
||||
}
|
||||
operator Callback1<FirstArgument>() const
|
||||
{
|
||||
return Callback1<FirstArgument>(getEnvironment(), thunk);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Forms a Callback from a non-const Environment reference and a free function which operates on a non-const Environment reference.
|
||||
///
|
||||
/// \dontinclude generic/callback.cpp
|
||||
/// \skipline ReferenceCaller example
|
||||
/// \until end example
|
||||
template<typename Environment, void (*func)(Environment&)>
|
||||
class ReferenceCaller
|
||||
{
|
||||
Environment& m_environment;
|
||||
public:
|
||||
ReferenceCaller(Environment& environment) : m_environment(environment)
|
||||
{
|
||||
}
|
||||
void* getEnvironment() const
|
||||
{
|
||||
return &m_environment;
|
||||
}
|
||||
static void thunk(void* environment)
|
||||
{
|
||||
(func)(*reinterpret_cast<Environment*>(environment));
|
||||
}
|
||||
operator Callback() const
|
||||
{
|
||||
return Callback(getEnvironment(), thunk);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Forms a Callback from a const Environment reference and a free function which operates on a const Environment reference.
|
||||
///
|
||||
/// \dontinclude generic/callback.cpp
|
||||
/// \skipline ReferenceCaller example
|
||||
/// \until end example
|
||||
template<typename Environment, void (*func)(const Environment&)>
|
||||
class ConstReferenceCaller
|
||||
{
|
||||
const Environment& m_environment;
|
||||
public:
|
||||
ConstReferenceCaller(const Environment& environment) : m_environment(environment)
|
||||
{
|
||||
}
|
||||
void* getEnvironment() const
|
||||
{
|
||||
return const_cast<Environment*>(&m_environment);
|
||||
}
|
||||
static void thunk(void* environment)
|
||||
{
|
||||
(func)(*reinterpret_cast<const Environment*>(environment));
|
||||
}
|
||||
operator Callback() const
|
||||
{
|
||||
return Callback(getEnvironment(), thunk);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Forms a Callback from a non-const Environment reference and a free function which operates on a non-const Environment reference and one other argument.
|
||||
template<typename Environment, typename FirstArgument, void (*func)(Environment&, FirstArgument)>
|
||||
class ReferenceCaller1
|
||||
{
|
||||
Environment& m_environment;
|
||||
public:
|
||||
ReferenceCaller1(Environment& environment) : m_environment(environment)
|
||||
{
|
||||
}
|
||||
void* getEnvironment() const
|
||||
{
|
||||
return &m_environment;
|
||||
}
|
||||
static void thunk(void* environment, FirstArgument firstArgument)
|
||||
{
|
||||
(func)(*reinterpret_cast<Environment*>(environment), firstArgument);
|
||||
}
|
||||
operator Callback1<FirstArgument>() const
|
||||
{
|
||||
return Callback1<FirstArgument>(getEnvironment(), thunk);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Forms a Callback from a const Environment reference and a free function which operates on a const Environment reference and one other argument.
|
||||
template<typename Environment, typename FirstArgument, void (*func)(const Environment&, FirstArgument)>
|
||||
class ConstReferenceCaller1
|
||||
{
|
||||
const Environment& m_environment;
|
||||
public:
|
||||
ConstReferenceCaller1(const Environment& environment) : m_environment(environment)
|
||||
{
|
||||
}
|
||||
void* getEnvironment() const
|
||||
{
|
||||
return const_cast<Environment*>(&m_environment);
|
||||
}
|
||||
static void thunk(void* environment, FirstArgument firstArgument)
|
||||
{
|
||||
(func)(*reinterpret_cast<const Environment*>(environment), firstArgument);
|
||||
}
|
||||
operator Callback1<FirstArgument>() const
|
||||
{
|
||||
return Callback1<FirstArgument>(getEnvironment(), thunk);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Forms a Callback from a non-const Environment pointer and a free function which operates on a non-const Environment pointer.
|
||||
template<typename Environment, void (*func)(Environment*)>
|
||||
class PointerCaller
|
||||
{
|
||||
Environment* m_environment;
|
||||
public:
|
||||
PointerCaller(Environment* environment) : m_environment(environment)
|
||||
{
|
||||
}
|
||||
void* getEnvironment() const
|
||||
{
|
||||
return m_environment;
|
||||
}
|
||||
static void thunk(void* environment)
|
||||
{
|
||||
(func)(reinterpret_cast<Environment*>(environment));
|
||||
}
|
||||
operator Callback() const
|
||||
{
|
||||
return Callback(getEnvironment(), thunk);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Forms a Callback from a const Environment pointer and a free function which operates on a const Environment pointer.
|
||||
template<typename Environment, void (*func)(const Environment*)>
|
||||
class ConstPointerCaller
|
||||
{
|
||||
const Environment* m_environment;
|
||||
public:
|
||||
ConstPointerCaller(const Environment* environment) : m_environment(environment)
|
||||
{
|
||||
}
|
||||
void* getEnvironment() const
|
||||
{
|
||||
return const_cast<Environment*>(m_environment);
|
||||
}
|
||||
static void thunk(void* environment)
|
||||
{
|
||||
(func)(reinterpret_cast<const Environment*>(environment));
|
||||
}
|
||||
operator Callback() const
|
||||
{
|
||||
return Callback(getEnvironment(), thunk);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Forms a Callback from a non-const Environment pointer and a free function which operates on a non-const Environment pointer and one other argument.
|
||||
template<typename Environment, typename FirstArgument, void (*func)(Environment*, FirstArgument)>
|
||||
class PointerCaller1
|
||||
{
|
||||
Environment* m_environment;
|
||||
public:
|
||||
PointerCaller1(Environment* environment) : m_environment(environment)
|
||||
{
|
||||
}
|
||||
void* getEnvironment() const
|
||||
{
|
||||
return m_environment;
|
||||
}
|
||||
static void thunk(void* environment, FirstArgument firstArgument)
|
||||
{
|
||||
(func)(reinterpret_cast<Environment*>(environment), firstArgument);
|
||||
}
|
||||
operator Callback1<FirstArgument>() const
|
||||
{
|
||||
return Callback1<FirstArgument>(getEnvironment(), thunk);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Forms a Callback from a const Environment pointer and a free function which operates on a const Environment pointer and one other argument.
|
||||
template<typename Environment, typename FirstArgument, void (*func)(const Environment*, FirstArgument)>
|
||||
class ConstPointerCaller1
|
||||
{
|
||||
const Environment* m_environment;
|
||||
public:
|
||||
ConstPointerCaller1(const Environment* environment) : m_environment(environment)
|
||||
{
|
||||
}
|
||||
void* getEnvironment() const
|
||||
{
|
||||
return const_cast<Environment*>(m_environment);
|
||||
}
|
||||
static void thunk(void* environment, FirstArgument firstArgument)
|
||||
{
|
||||
(func)(reinterpret_cast<const Environment*>(environment), firstArgument);
|
||||
}
|
||||
operator Callback1<FirstArgument>() const
|
||||
{
|
||||
return Callback1<FirstArgument>(getEnvironment(), thunk);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// \brief Forms a Callback from a free function which takes no arguments.
|
||||
template<void (*func)()>
|
||||
class FreeCaller
|
||||
{
|
||||
public:
|
||||
void* getEnvironment() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static void thunk(void*)
|
||||
{
|
||||
(func)();
|
||||
}
|
||||
operator Callback() const
|
||||
{
|
||||
return Callback(getEnvironment(), thunk);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Forms a Callback from a free function which takes a single argument.
|
||||
template<typename FirstArgument, void (*func)(FirstArgument)>
|
||||
class FreeCaller1
|
||||
{
|
||||
public:
|
||||
void* getEnvironment() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static void thunk(void*, FirstArgument firstArgument)
|
||||
{
|
||||
(func)(firstArgument);
|
||||
}
|
||||
operator Callback1<FirstArgument>() const
|
||||
{
|
||||
return Callback1<FirstArgument>(getEnvironment(), thunk);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// \brief Constructs a Callback from a non-const \p functor with zero arguments.
|
||||
///
|
||||
/// \param Functor Must define \c operator()().
|
||||
template<typename Functor>
|
||||
inline Callback makeCallback(Functor& functor)
|
||||
{
|
||||
return Callback(MemberCaller<Functor, &Functor::operator()>(functor));
|
||||
}
|
||||
|
||||
/// \brief Constructs a Callback from a const \p functor with zero arguments.
|
||||
///
|
||||
/// \param Functor Must define const \c operator()().
|
||||
template<typename Functor>
|
||||
inline Callback makeCallback(const Functor& functor)
|
||||
{
|
||||
return Callback(ConstMemberCaller<Functor, &Functor::operator()>(functor));
|
||||
}
|
||||
|
||||
/// \brief Constructs a Callback1 from a non-const \p functor with one argument.
|
||||
///
|
||||
/// \param Functor Must define \c first_argument_type and \c operator()(first_argument_type).
|
||||
template<typename Functor>
|
||||
inline Callback1<typename Functor::first_argument_type> makeCallback1(Functor& functor)
|
||||
{
|
||||
typedef typename Functor::first_argument_type FirstArgument;
|
||||
return Callback1<FirstArgument>(MemberCaller1<Functor, FirstArgument, &Functor::operator()>(functor));
|
||||
}
|
||||
|
||||
/// \brief Constructs a Callback1 from a const \p functor with one argument.
|
||||
///
|
||||
/// \param Functor Must define \c first_argument_type and const \c operator()(first_argument_type).
|
||||
template<typename Functor>
|
||||
inline Callback1<typename Functor::first_argument_type> makeCallback1(const Functor& functor)
|
||||
{
|
||||
typedef typename Functor::first_argument_type FirstArgument;
|
||||
return Callback1<FirstArgument>(ConstMemberCaller1<Functor, FirstArgument, &Functor::operator()>(functor));
|
||||
}
|
||||
|
||||
#endif
|
||||
40
libs/generic/constant.cpp
Normal file
40
libs/generic/constant.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
Copyright (C) 2001-2006, William Joseph.
|
||||
All Rights Reserved.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GtkRadiant is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "constant.h"
|
||||
|
||||
#if defined(_DEBUG) || defined(DOXYGEN)
|
||||
|
||||
namespace ExampleConstant
|
||||
{
|
||||
class Bleh
|
||||
{
|
||||
public:
|
||||
|
||||
STRING_CONSTANT(Name, "Bleh");
|
||||
INTEGER_CONSTANT(Version, 1);
|
||||
};
|
||||
|
||||
int version = Bleh::Version();
|
||||
const char* name = Bleh::Name();
|
||||
}
|
||||
|
||||
#endif
|
||||
48
libs/generic/constant.h
Normal file
48
libs/generic/constant.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
Copyright (C) 2001-2006, William Joseph.
|
||||
All Rights Reserved.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GtkRadiant is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if !defined(INCLUDED_GENERIC_CONSTANT_H)
|
||||
#define INCLUDED_GENERIC_CONSTANT_H
|
||||
|
||||
/// \file
|
||||
/// \brief Language extensions for constants that are guaranteed to be evaluated at compile-time.
|
||||
|
||||
/// \brief A compile-time-constant as a type.
|
||||
template<typename Type>
|
||||
struct ConstantWrapper
|
||||
{
|
||||
typedef typename Type::Value Value;
|
||||
operator Value() const
|
||||
{
|
||||
return Type::evaluate();
|
||||
}
|
||||
};
|
||||
template<typename TextOutputStreamType, typename Type>
|
||||
inline TextOutputStreamType& ostream_write(TextOutputStreamType& ostream, const ConstantWrapper<Type>& c)
|
||||
{
|
||||
return ostream_write(ostream, typename Type::Value(c));
|
||||
}
|
||||
|
||||
#define TYPE_CONSTANT(name, value, type) struct name##_CONSTANT_ { typedef type Value; static Value evaluate() { return value; } }; typedef ConstantWrapper<name##_CONSTANT_> name
|
||||
#define STRING_CONSTANT(name, value) TYPE_CONSTANT(name, value, const char*)
|
||||
#define INTEGER_CONSTANT(name, value) TYPE_CONSTANT(name, value, int)
|
||||
|
||||
#endif
|
||||
23
libs/generic/enumeration.cpp
Normal file
23
libs/generic/enumeration.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
Copyright (C) 2001-2006, William Joseph.
|
||||
All Rights Reserved.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GtkRadiant is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "enumeration.h"
|
||||
|
||||
60
libs/generic/enumeration.h
Normal file
60
libs/generic/enumeration.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
Copyright (C) 2001-2006, William Joseph.
|
||||
All Rights Reserved.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GtkRadiant is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if !defined(INCLUDED_GENERIC_ENUMERATION_H)
|
||||
#define INCLUDED_GENERIC_ENUMERATION_H
|
||||
|
||||
/// \file
|
||||
/// \brief Type safe enumeration.
|
||||
|
||||
/// \brief An enumerated value.
|
||||
///
|
||||
/// - Can be forward-declared when the definition of Enumeration is unknown.
|
||||
/// - Can only be constructed from valid enumerated values.
|
||||
/// - Can only be compared with others of the same type.
|
||||
///
|
||||
/// \param Enumeration A type that contains an enum \c Value of the allowed values of the enumeration.
|
||||
template<typename Enumeration>
|
||||
class EnumeratedValue : public Enumeration
|
||||
{
|
||||
typename Enumeration::Value m_value;
|
||||
public:
|
||||
explicit EnumeratedValue(typename Enumeration::Value value) : m_value(value)
|
||||
{
|
||||
}
|
||||
typename Enumeration::Value get() const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Enumeration>
|
||||
inline bool operator==(EnumeratedValue<Enumeration> self, EnumeratedValue<Enumeration> other)
|
||||
{
|
||||
return self.get() == other.get();
|
||||
}
|
||||
template<typename Enumeration>
|
||||
inline bool operator!=(EnumeratedValue<Enumeration> self, EnumeratedValue<Enumeration> other)
|
||||
{
|
||||
return !operator==(self, other);
|
||||
}
|
||||
|
||||
#endif
|
||||
41
libs/generic/object.cpp
Normal file
41
libs/generic/object.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
Copyright (C) 2001-2006, William Joseph.
|
||||
All Rights Reserved.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GtkRadiant is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "object.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
class Blah
|
||||
{
|
||||
int i;
|
||||
public:
|
||||
Blah()
|
||||
{
|
||||
i = 3;
|
||||
}
|
||||
};
|
||||
|
||||
void Test()
|
||||
{
|
||||
char storage[sizeof(Blah)];
|
||||
constructor(*reinterpret_cast<Blah*>(storage));
|
||||
}
|
||||
}
|
||||
98
libs/generic/object.h
Normal file
98
libs/generic/object.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
Copyright (C) 2001-2006, William Joseph.
|
||||
All Rights Reserved.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GtkRadiant is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if !defined(INCLUDED_GENERIC_OBJECT_H)
|
||||
#define INCLUDED_GENERIC_OBJECT_H
|
||||
|
||||
/// \file
|
||||
/// \brief Convenience functions (syntactic sugar) to wrap explicit constructor (aka in-place 'new') and destructor calls.
|
||||
///
|
||||
/// Use makeReference() to wrap non-const-reference constructor parameters.
|
||||
|
||||
#if _MSC_VER > 1000 && defined(WIN32)
|
||||
#pragma warning(disable:4345) // behavior change: an object of POD type constructed with an initializer of the form () will be default-initialized
|
||||
#endif
|
||||
|
||||
#include <new>
|
||||
|
||||
template<typename Type>
|
||||
inline void constructor(Type& object)
|
||||
{
|
||||
new(&object) Type();
|
||||
}
|
||||
|
||||
template<typename Type, typename T1>
|
||||
inline void constructor(Type& object, const T1& t1)
|
||||
{
|
||||
new(&object) Type(t1);
|
||||
}
|
||||
|
||||
template<typename Type, typename T1, typename T2>
|
||||
inline void constructor(Type& object, const T1& t1, const T2& t2)
|
||||
{
|
||||
new(&object) Type(t1, t2);
|
||||
}
|
||||
|
||||
template<typename Type, typename T1, typename T2, typename T3>
|
||||
inline void constructor(Type& object, const T1& t1, const T2& t2, const T3& t3)
|
||||
{
|
||||
new(&object) Type(t1, t2, t3);
|
||||
}
|
||||
|
||||
template<typename Type, typename T1, typename T2, typename T3, typename T4>
|
||||
inline void constructor(Type& object, const T1& t1, const T2& t2, const T3& t3, const T4& t4)
|
||||
{
|
||||
new(&object) Type(t1, t2, t3, t4);
|
||||
}
|
||||
|
||||
template<typename Type, typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
inline void constructor(Type& object, const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5)
|
||||
{
|
||||
new(&object) Type(t1, t2, t3, t4, t5);
|
||||
}
|
||||
|
||||
template<typename Type, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
|
||||
inline void constructor(Type& object, const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6)
|
||||
{
|
||||
new(&object) Type(t1, t2, t3, t4, t5, t6);
|
||||
}
|
||||
|
||||
template<typename Type, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
|
||||
inline void constructor(Type& object, const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6, const T7& t7)
|
||||
{
|
||||
new(&object) Type(t1, t2, t3, t4, t5, t6, t7);
|
||||
}
|
||||
|
||||
template<typename Type, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
||||
inline void constructor(Type& object, const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6, const T7& t7, const T8& t8)
|
||||
{
|
||||
new(&object) Type(t1, t2, t3, t4, t5, t6, t7, t8);
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
inline void destructor(Type& object)
|
||||
{
|
||||
object.~Type();
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
22
libs/generic/reference.cpp
Normal file
22
libs/generic/reference.cpp
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
Copyright (C) 2001-2006, William Joseph.
|
||||
All Rights Reserved.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GtkRadiant is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "reference.h"
|
||||
131
libs/generic/reference.h
Normal file
131
libs/generic/reference.h
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
Copyright (C) 2001-2006, William Joseph.
|
||||
All Rights Reserved.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GtkRadiant is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if !defined(INCLUDED_GENERIC_REFERENCE_H)
|
||||
#define INCLUDED_GENERIC_REFERENCE_H
|
||||
|
||||
/// \file
|
||||
/// \brief Wrappers to allow storing objects in templated containers using 'reference' semantics.
|
||||
|
||||
/// \brief A reference to a mutable object.
|
||||
/// Has 'reference' semantics, except for \c 'operator==' and \c 'operator.'.
|
||||
/// \param Type The type of the referenced object.
|
||||
template<typename Type>
|
||||
class Reference
|
||||
{
|
||||
Type* m_contained;
|
||||
public:
|
||||
explicit Reference(Type& contained) : m_contained(&contained)
|
||||
{
|
||||
}
|
||||
Type& operator*() const
|
||||
{
|
||||
return *m_contained;
|
||||
}
|
||||
Type* operator->() const
|
||||
{
|
||||
return m_contained;
|
||||
}
|
||||
operator Type&() const
|
||||
{
|
||||
return *m_contained;
|
||||
}
|
||||
Type& get() const
|
||||
{
|
||||
return *m_contained;
|
||||
}
|
||||
Type* get_pointer() const
|
||||
{
|
||||
return m_contained;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Type>
|
||||
bool operator<(const Reference<Type>& self, const Reference<Type>& other)
|
||||
{
|
||||
return self.get() < other.get();
|
||||
}
|
||||
template<typename Type>
|
||||
bool operator==(const Reference<Type>& self, const Reference<Type>& other)
|
||||
{
|
||||
return self.get() == other.get();
|
||||
}
|
||||
|
||||
/// \brief construct a reference to a mutable object.
|
||||
template<typename Type>
|
||||
inline Reference<Type> makeReference(Type& value)
|
||||
{
|
||||
return Reference<Type>(value);
|
||||
}
|
||||
|
||||
/// \brief A reference to a non-mutable object.
|
||||
/// Has 'reference' semantics, except for \c 'operator==' and \c 'operator.'.
|
||||
/// \param Type The type of the referenced object.
|
||||
template<typename Type>
|
||||
class ConstReference
|
||||
{
|
||||
const Type* m_contained;
|
||||
public:
|
||||
explicit ConstReference(const Type& contained) : m_contained(&contained)
|
||||
{
|
||||
}
|
||||
const Type& operator*() const
|
||||
{
|
||||
return *m_contained;
|
||||
}
|
||||
const Type* operator->() const
|
||||
{
|
||||
return m_contained;
|
||||
}
|
||||
operator const Type&() const
|
||||
{
|
||||
return *m_contained;
|
||||
}
|
||||
const Type& get() const
|
||||
{
|
||||
return *m_contained;
|
||||
}
|
||||
const Type* get_pointer() const
|
||||
{
|
||||
return m_contained;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Type>
|
||||
bool operator<(const ConstReference<Type>& self, const ConstReference<Type>& other)
|
||||
{
|
||||
return self.get() < other.get();
|
||||
}
|
||||
template<typename Type>
|
||||
bool operator==(const ConstReference<Type>& self, const ConstReference<Type>& other)
|
||||
{
|
||||
return self.get() == other.get();
|
||||
}
|
||||
|
||||
/// \brief construct a reference to a non-mutable object.
|
||||
template<typename Type>
|
||||
inline ConstReference<Type> makeReference(const Type& value)
|
||||
{
|
||||
return ConstReference<Type>(value);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
22
libs/generic/referencecounted.cpp
Normal file
22
libs/generic/referencecounted.cpp
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
Copyright (C) 2001-2006, William Joseph.
|
||||
All Rights Reserved.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GtkRadiant is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "referencecounted.h"
|
||||
207
libs/generic/referencecounted.h
Normal file
207
libs/generic/referencecounted.h
Normal file
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
Copyright (C) 2001-2006, William Joseph.
|
||||
All Rights Reserved.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GtkRadiant is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if !defined(INCLUDED_GENERIC_REFERENCECOUNTED_H)
|
||||
#define INCLUDED_GENERIC_REFERENCECOUNTED_H
|
||||
|
||||
/// \file
|
||||
/// \brief 'smart' pointers and references.
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
template<typename Type>
|
||||
class IncRefDecRefCounter
|
||||
{
|
||||
public:
|
||||
void increment(Type& value)
|
||||
{
|
||||
value.IncRef();
|
||||
}
|
||||
void decrement(Type& value)
|
||||
{
|
||||
value.DecRef();
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief A smart-pointer that uses a counter stored in the object pointed-to.
|
||||
template<typename Type, typename Counter = IncRefDecRefCounter<Type> >
|
||||
class SmartPointer : public Counter
|
||||
{
|
||||
Type* m_value;
|
||||
public:
|
||||
|
||||
SmartPointer(const SmartPointer& other)
|
||||
: m_value(other.m_value)
|
||||
{
|
||||
Counter::increment(*m_value);
|
||||
}
|
||||
explicit SmartPointer(Type* value)
|
||||
: m_value(value)
|
||||
{
|
||||
Counter::increment(*m_value);
|
||||
}
|
||||
~SmartPointer()
|
||||
{
|
||||
Counter::decrement(*m_value);
|
||||
}
|
||||
SmartPointer& operator=(const SmartPointer& other)
|
||||
{
|
||||
SmartPointer temp(other);
|
||||
temp.swap(*this);
|
||||
return *this;
|
||||
}
|
||||
SmartPointer& operator=(Type* value)
|
||||
{
|
||||
SmartPointer temp(value);
|
||||
temp.swap(*this);
|
||||
return *this;
|
||||
}
|
||||
void swap(SmartPointer& other)
|
||||
{
|
||||
std::swap(m_value, other.m_value);
|
||||
}
|
||||
|
||||
operator Type*() const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
Type& operator*() const
|
||||
{
|
||||
return *m_value;
|
||||
}
|
||||
Type* operator->() const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
Type* get() const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Type>
|
||||
inline bool operator<(const SmartPointer<Type>& self, const SmartPointer<Type>& other)
|
||||
{
|
||||
return self.get() < other.get();
|
||||
}
|
||||
template<typename Type>
|
||||
inline bool operator==(const SmartPointer<Type>& self, const SmartPointer<Type>& other)
|
||||
{
|
||||
return self.get() == other.get();
|
||||
}
|
||||
template<typename Type>
|
||||
inline bool operator!=(const SmartPointer<Type>& self, const SmartPointer<Type>& other)
|
||||
{
|
||||
return !::operator==(self, other);
|
||||
}
|
||||
|
||||
namespace std
|
||||
{
|
||||
/// \brief Swaps the values of \p self and \p other.
|
||||
/// Overloads std::swap().
|
||||
template<typename Type>
|
||||
inline void swap(SmartPointer<Type>& self, SmartPointer<Type>& other)
|
||||
{
|
||||
self.swap(other);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// \brief A smart-reference that uses a counter stored in the object pointed-to.
|
||||
template<typename Type, typename Counter = IncRefDecRefCounter<Type> >
|
||||
class SmartReference : public Counter
|
||||
{
|
||||
Type* m_value;
|
||||
public:
|
||||
|
||||
SmartReference(const SmartReference& other)
|
||||
: m_value(other.m_value)
|
||||
{
|
||||
Counter::increment(*m_value);
|
||||
}
|
||||
explicit SmartReference(Type& value)
|
||||
: m_value(&value)
|
||||
{
|
||||
Counter::increment(*m_value);
|
||||
}
|
||||
~SmartReference()
|
||||
{
|
||||
Counter::decrement(*m_value);
|
||||
}
|
||||
SmartReference& operator=(const SmartReference& other)
|
||||
{
|
||||
SmartReference temp(other);
|
||||
temp.swap(*this);
|
||||
return *this;
|
||||
}
|
||||
SmartReference& operator=(Type& value)
|
||||
{
|
||||
SmartReference temp(value);
|
||||
temp.swap(*this);
|
||||
return *this;
|
||||
}
|
||||
void swap(SmartReference& other)
|
||||
{
|
||||
std::swap(m_value, other.m_value);
|
||||
}
|
||||
|
||||
operator Type&() const
|
||||
{
|
||||
return *m_value;
|
||||
}
|
||||
Type& get() const
|
||||
{
|
||||
return *m_value;
|
||||
}
|
||||
Type* get_pointer() const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Type>
|
||||
inline bool operator<(const SmartReference<Type>& self, const SmartReference<Type>& other)
|
||||
{
|
||||
return self.get() < other.get();
|
||||
}
|
||||
template<typename Type>
|
||||
inline bool operator==(const SmartReference<Type>& self, const SmartReference<Type>& other)
|
||||
{
|
||||
return self.get() == other.get();
|
||||
}
|
||||
template<typename Type>
|
||||
inline bool operator!=(const SmartReference<Type>& self, const SmartReference<Type>& other)
|
||||
{
|
||||
return !::operator==(self, other);
|
||||
}
|
||||
|
||||
namespace std
|
||||
{
|
||||
/// \brief Swaps the values of \p self and \p other.
|
||||
/// Overloads std::swap().
|
||||
template<typename Type>
|
||||
inline void swap(SmartReference<Type>& self, SmartReference<Type>& other)
|
||||
{
|
||||
self.swap(other);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
133
libs/generic/static.cpp
Normal file
133
libs/generic/static.cpp
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
Copyright (C) 2001-2006, William Joseph.
|
||||
All Rights Reserved.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GtkRadiant is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "static.h"
|
||||
|
||||
#if defined(_DEBUG) || defined(DOXYGEN)
|
||||
|
||||
namespace ExampleStatic
|
||||
{
|
||||
// Static example
|
||||
// ---- myclass.h
|
||||
class MyClass
|
||||
{
|
||||
public:
|
||||
int value;
|
||||
MyClass() : value(3)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
typedef Static<MyClass> StaticMyClass;
|
||||
|
||||
// ---- main.cpp
|
||||
class DynamicInitialisation
|
||||
{
|
||||
public:
|
||||
DynamicInitialisation()
|
||||
{
|
||||
// StaticMyClass::instance() may be invalid here because construction order is undefined
|
||||
}
|
||||
};
|
||||
|
||||
DynamicInitialisation g_dynamicInitialisation;
|
||||
|
||||
void duringMain()
|
||||
{
|
||||
int bar = StaticMyClass::instance().value;
|
||||
}
|
||||
// end example
|
||||
}
|
||||
|
||||
namespace ExampleLazyStatic
|
||||
{
|
||||
// LazyStatic example
|
||||
// ---- myclass.h
|
||||
class MyClass
|
||||
{
|
||||
public:
|
||||
int value;
|
||||
MyClass() : value(3)
|
||||
{
|
||||
}
|
||||
// destructor will never be called
|
||||
};
|
||||
|
||||
typedef LazyStatic<MyClass> StaticMyClass;
|
||||
|
||||
// ---- main.cpp
|
||||
class DynamicInitialisation
|
||||
{
|
||||
public:
|
||||
DynamicInitialisation()
|
||||
{
|
||||
int bar = StaticMyClass::instance().value;
|
||||
}
|
||||
};
|
||||
|
||||
DynamicInitialisation g_dynamicInitialisation;
|
||||
|
||||
void duringMain()
|
||||
{
|
||||
int bar = StaticMyClass::instance().value;
|
||||
}
|
||||
// end example
|
||||
}
|
||||
|
||||
namespace ExampleSmartStatic
|
||||
{
|
||||
// SmartStatic example
|
||||
// ---- myclass.h
|
||||
class MyClass
|
||||
{
|
||||
public:
|
||||
int value;
|
||||
MyClass() : value(3)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
typedef CountedStatic<MyClass> StaticMyClass;
|
||||
|
||||
// ---- main.cpp
|
||||
class DynamicInitialisation
|
||||
{
|
||||
public:
|
||||
DynamicInitialisation()
|
||||
{
|
||||
// StaticMyClass::instance() is invalid before the ref is constructed
|
||||
SmartStatic<MyClass> ref;
|
||||
int bar = ref.instance().value;
|
||||
|
||||
SmartStatic<MyClass> ref2; // any number of instances are allowed.
|
||||
}
|
||||
};
|
||||
|
||||
DynamicInitialisation g_dynamicInitialisation;
|
||||
|
||||
void duringMain()
|
||||
{
|
||||
int bar = SmartStatic<MyClass>().instance().value; // an instance can be a temporary
|
||||
}
|
||||
// end example
|
||||
}
|
||||
|
||||
#endif
|
||||
143
libs/generic/static.h
Normal file
143
libs/generic/static.h
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
Copyright (C) 2001-2006, William Joseph.
|
||||
All Rights Reserved.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GtkRadiant is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if !defined(INCLUDED_GENERIC_STATIC_H)
|
||||
#define INCLUDED_GENERIC_STATIC_H
|
||||
|
||||
/// \file
|
||||
/// \brief Template techniques for instantiating singletons.
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
/// \brief A singleton which is statically initialised.
|
||||
///
|
||||
/// \param Type The singleton object type.
|
||||
///
|
||||
/// \dontinclude generic/static.cpp
|
||||
/// \skipline Static example
|
||||
/// \until end example
|
||||
template<typename Type>
|
||||
class Static
|
||||
{
|
||||
static Type m_instance;
|
||||
public:
|
||||
static Type& instance()
|
||||
{
|
||||
return m_instance;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Type>
|
||||
Type Static<Type>::m_instance;
|
||||
|
||||
|
||||
/// \brief A singleton which is lazily initialised.
|
||||
/// The instance is constructed the first time it is referenced, and is never destroyed.
|
||||
///
|
||||
/// \param Type The singleton object type.
|
||||
///
|
||||
/// \dontinclude generic/static.cpp
|
||||
/// \skipline LazyStatic example
|
||||
/// \until end example
|
||||
template<typename Type>
|
||||
class LazyStatic
|
||||
{
|
||||
static Type* m_instance; // this will be initialised to 0 by the CRT, according to the c++ standard
|
||||
public:
|
||||
static Type& instance()
|
||||
{
|
||||
if(m_instance == 0)
|
||||
{
|
||||
m_instance = new Type; // allocate using 'new' to get the correct alignment
|
||||
}
|
||||
return *m_instance;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Type>
|
||||
Type* LazyStatic<Type>::m_instance;
|
||||
|
||||
|
||||
/// \brief A singleton which keeps a count of the number of times it is referenced.
|
||||
///
|
||||
/// The instance is constructed when its reference count changes from 0 to 1 and destroyed when its reference count changes from 1 to 0.
|
||||
/// Use with SmartStatic.
|
||||
///
|
||||
/// \param Type The singleton object type.
|
||||
template<typename Type>
|
||||
class CountedStatic
|
||||
{
|
||||
static std::size_t m_refcount; // this will be initialised to 0 by the CRT, according to the c++ standard
|
||||
static Type* m_instance;
|
||||
public:
|
||||
static Type& instance()
|
||||
{
|
||||
return *m_instance;
|
||||
}
|
||||
static void capture()
|
||||
{
|
||||
if(++m_refcount == 1)
|
||||
{
|
||||
m_instance = new Type; // allocate using 'new' to get the correct alignment
|
||||
}
|
||||
}
|
||||
static void release()
|
||||
{
|
||||
if(--m_refcount == 0)
|
||||
{
|
||||
delete m_instance;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Type>
|
||||
std::size_t CountedStatic<Type>::m_refcount; // this will be initialised to 0 by the CRT, according to the c++ standard
|
||||
template<typename Type>
|
||||
Type* CountedStatic<Type>::m_instance;
|
||||
|
||||
/// \brief A reference to a CountedStatic.
|
||||
/// Guarantees that CountedStatic<Type> will be constructed for the lifetime of this object.
|
||||
///
|
||||
/// \param Type The type parameter of the CountedStatic to reference.
|
||||
///
|
||||
/// \dontinclude generic/static.cpp
|
||||
/// \skipline SmartStatic example
|
||||
/// \until end example
|
||||
template<typename Type>
|
||||
class SmartStatic
|
||||
{
|
||||
public:
|
||||
SmartStatic()
|
||||
{
|
||||
CountedStatic<Type>::capture();
|
||||
}
|
||||
~SmartStatic()
|
||||
{
|
||||
CountedStatic<Type>::release();
|
||||
}
|
||||
Type& instance()
|
||||
{
|
||||
return CountedStatic<Type>::instance();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user