The GtkRadiant sources as originally released under the GPL license.

This commit is contained in:
Travis Bradshaw
2012-01-31 15:20:35 -06:00
commit 0991a5ce8b
1590 changed files with 431941 additions and 0 deletions

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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

View 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"

View 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
View 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
View 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

View 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
View 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

View 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"

View 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
View 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
View 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