Documented some more of hz.

This commit is contained in:
Alexander Shaduri
2011-08-17 20:15:58 +00:00
parent 42da49c5c1
commit 0f89010225
11 changed files with 510 additions and 291 deletions
+41 -39
View File
@@ -3,6 +3,11 @@
(C) 2008 - 2011 Alexander Shaduri <ashaduri 'at' gmail.com>
License: See LICENSE_zlib.txt file
***************************************************************************/
/// \file
/// \author Alexander Shaduri
/// \ingroup hz
/// \weakgroup hz
/// @{
#ifndef HZ_INSTANCE_MANAGER_H
#define HZ_INSTANCE_MANAGER_H
@@ -17,37 +22,35 @@
namespace hz {
// Inherit from this class to generate a single- or multi-instance
// objects, e.g. windows.
/**
Inherit this class to have a single- or multi-instance objects, e.g. windows.
Single-instance variant uses locks to protect the data when
manipulating it through its functions. If you intend to write to
the pointed object and use it in separate threads, you will
need to lock it manually.
// Single-instance variant uses locks to protect the data when
// manipulating it through its functions. If you intend to write to
// the pointed object and use it in separate threads, you will
// need to lock it manually.
Multi-instance variant doesn't store any instances itself, so
you are expected to perform any necessary locking with the
pointers you hold.
// Multi-instance variant doesn't store any instances itself, so
// you are expected to perform any necessary locking with the
// pointers you hold.
// Single-instance specialization is defined below.
// SingleLockPolicy has no effect if MultiInstance is true.
\c SingleLockPolicy has no effect if MultiInstance is true.
*/
template<class Child, bool MultiInstance, class SingleLockPolicy = SyncPolicyNone>
class InstanceManager : public hz::noncopyable { // disallow copying
protected:
// can't construct / delete this directly! use create() and destroy()
/// Can't construct / delete this directly! use create() and destroy()
InstanceManager() { }
/// Virtual destructor (protected, can't delete this directly, use destroy()).
virtual ~InstanceManager() { }
public:
// Create a new instance or return an already created one if single-instance.
// If single-instance, the call will be serialized.
/// Create a new instance or return an already created one if single-instance.
/// If single-instance, the call will be serialized.
static Child* create()
{
Child* o = new Child;
@@ -56,9 +59,9 @@ class InstanceManager : public hz::noncopyable { // disallow copying
}
// Destroy an instance. "instance" parameter must be passed if using
// multi-instance object. If single-instance, "instance" has no effect.
// If single-instance, the call will be serialized.
/// Destroy an instance. \c instance must be passed if using
/// multi-instance object. If single-instance, \c instance has no effect.
/// If single-instance, the call will be serialized.
static void destroy(Child* instance = 0)
{
if (instance) {
@@ -74,29 +77,32 @@ class InstanceManager : public hz::noncopyable { // disallow copying
// These functions are called when the object instance is
// created or destroyed through ::create() and ::destroy().
// called from create(), right after constructor.
/// Called from create(), right after constructor.
virtual void obj_create() { }
// called from destroy(), right before destructor.
/// Called from destroy(), right before destructor.
virtual void obj_destroy() { }
// We have these functions for multi-instance variant too to
// support transparently switching between them.
// for single-instance objects only
/// Returns true if there is a valid single-instance object.
/// In multi-instance version this always returns false.
static bool has_single_instance(bool do_lock = true)
{
return false;
}
// for single-instance objects only
/// Returns the instance if there is a valid single-instance one.
/// In multi-instance version this always returns 0.
static Child* get_single_instance(bool do_lock = true)
{
return 0;
}
// for single-instance objects only
/// Set single-instance object.
/// This function has no effect in multi-instance version.
static void set_single_instance(Child* instance, bool do_lock = true)
{ }
@@ -105,10 +111,9 @@ class InstanceManager : public hz::noncopyable { // disallow copying
// Single-instance specialization
/// Single-instance specialization
template<class Child, class SingleLockPolicy>
class InstanceManager<Child, false, SingleLockPolicy> : public hz::noncopyable { // disallow copying
protected:
InstanceManager() { }
@@ -147,13 +152,8 @@ class InstanceManager<Child, false, SingleLockPolicy> : public hz::noncopyable {
protected:
// These functions are called when the object instance is
// created or destroyed through ::create() and ::destroy().
// called from create(), right after constructor.
virtual void obj_create() { }
// called from destroy(), right before destructor.
virtual void obj_destroy() { }
@@ -177,8 +177,8 @@ class InstanceManager<Child, false, SingleLockPolicy> : public hz::noncopyable {
// if an object is allowed to have a single instance only, these are needed.
static Child* instance_;
static typename SingleLockPolicy::Mutex instance_mutex_;
static Child* instance_; ///< Single instance pointer
static typename SingleLockPolicy::Mutex instance_mutex_; ///< Single instance pointer mutex
// static const bool multi_instance_ = false;
@@ -187,11 +187,11 @@ class InstanceManager<Child, false, SingleLockPolicy> : public hz::noncopyable {
// Singleton instance (or whatever).
// This is a definition of class template's static member variable
// (it can be in a header (as opposed to cpp) if it's class template member).
// This will generate different instances as long as the class type is different.
// By passing the child's class type as template parameter we guarantee that.
/// Single instance pointer.
/// This is a definition of class template's static member variable
/// (it can be in a header (as opposed to cpp) if it's class template member).
/// This will generate different instances as long as the class type is different.
/// By passing the child's class type as template parameter we guarantee that.
template<class Child, class SingleLockPolicy>
Child* InstanceManager<Child, false, SingleLockPolicy>::instance_ = 0;
@@ -210,3 +210,5 @@ typename SingleLockPolicy::Mutex InstanceManager<Child, false, SingleLockPolicy>
#endif
/// @}
+144 -64
View File
@@ -4,29 +4,34 @@
(C) 2008 - 2011 Alexander Shaduri <ashaduri 'at' gmail.com>
License: See LICENSE_boost_1_0.txt file
***************************************************************************/
/// \file
/// \author Peter Dimov
/// \author Alexander Shaduri
/// \ingroup hz
/// \weakgroup hz
/// @{
#ifndef HZ_INTRUSIVE_PTR_H
#define HZ_INTRUSIVE_PTR_H
#include "hz_config.h" // feature macros
/*
/**
\file
Intrusive reference-counting smart pointer, based on boost::intrusive_ptr.
Original notes and copyright info follow:
intrusive_ptr.hpp
Copyright (c) 2001, 2002 Peter Dimov
Distributed under the Boost Software License, Version 1.0. (See
accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
See http://www.boost.org/libs/smart_ptr/intrusive_ptr.html for documentation.
*/
// intrusive_ptr.hpp
//
// Copyright (c) 2001, 2002 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/smart_ptr/intrusive_ptr.html for documentation.
#include <cstddef> // std::size_t
#include <cstring> // strncpy / strlen
@@ -40,11 +45,19 @@ Original notes and copyright info follow:
#include "exceptions.h" // THROW_FATAL
// This enables reference count and lock tracing (very verbose)
// #define INTRUSIVE_PTR_TRACING 1
/// \def INTRUSIVE_PTR_TRACING
/// Defined to 0 (default if undefined) or 1. This enables reference count
/// and lock tracing (very verbose).
#ifndef INTRUSIVE_PTR_TRACING
#define INTRUSIVE_PTR_TRACING 0
#endif
// This enables runtime checks for errors (with exception throwing)
// #define INTRUSIVE_PTR_RUNTIME_CHECKS 1
/// \def INTRUSIVE_PTR_RUNTIME_CHECKS
/// Defined to 0 or 1 (default if undefined). This enables runtime checks
/// for errors (with exception throwing).
#ifndef INTRUSIVE_PTR_RUNTIME_CHECKS
#define INTRUSIVE_PTR_RUNTIME_CHECKS 1
#endif
@@ -62,11 +75,11 @@ namespace hz {
// This is thrown on refcount / null pointer errors, if DEBUG_BUILD
// or INTRUSIVE_PTR_TRACING are defined.
/// This is thrown on refcount / null pointer errors, if \c DEBUG_BUILD
/// or \ref INTRUSIVE_PTR_TRACING are defined.
struct intrusive_ptr_error : virtual public std::exception { // from <exception>
/// Constructor
intrusive_ptr_error(const char* msg)
#if !(defined DISABLE_RTTI && DISABLE_RTTI)
: type_(typeid(void))
@@ -77,6 +90,7 @@ struct intrusive_ptr_error : virtual public std::exception { // from <exception
}
#if !(defined DISABLE_RTTI && DISABLE_RTTI)
/// Constructor
intrusive_ptr_error(const char* msg, const std::type_info& type)
: msg_(0), type_(type)
{
@@ -92,27 +106,35 @@ struct intrusive_ptr_error : virtual public std::exception { // from <exception
}
#endif
/// Virtual destructor
virtual ~intrusive_ptr_error() throw()
{
delete[] msg_;
msg_ = 0; // protect from double-deletion compiler bugs
}
// Note: messages in exceptions are not newline-terminated.
/// Reimplemented from std::exception.
/// Note: messages in exceptions are not newline-terminated.
virtual const char* what() const throw()
{
return msg_;
}
char* msg_;
char* msg_; ///< Error message
#if !(defined DISABLE_RTTI && DISABLE_RTTI)
const std::type_info& type_;
const std::type_info& type_; ///< Type information of the pointee
#endif
};
// Basically, if no runtime checks - disregard cond.
// If no tracing, disregard messages to cerr.
/// \def INTRUSIVE_PTR_THROW(cond, type, msg)
/// If \ref INTRUSIVE_PTR_RUNTIME_CHECKS is 1, check
/// \c cond and throw \ref intrusive_ptr_error. If \ref INTRUSIVE_PTR_RUNTIME_CHECKS
/// is 0, ignore \c cond and don't throw anything.
/// If \ref INTRUSIVE_PTR_TRACING is 1, print message and some
/// additional information to std::cerr.
#if !(defined DISABLE_RTTI && DISABLE_RTTI)
@@ -127,7 +149,9 @@ struct intrusive_ptr_error : virtual public std::exception { // from <exception
#elif defined INTRUSIVE_PTR_TRACING && INTRUSIVE_PTR_TRACING
#define INTRUSIVE_PTR_THROW(cond, type, msg) \
std::cerr << (msg) << " Type: " << type.name() << "\n";
{ \
std::cerr << (msg) << " Type: " << type.name() << "\n"; \
}
#elif defined INTRUSIVE_PTR_RUNTIME_CHECKS && INTRUSIVE_PTR_RUNTIME_CHECKS
#define INTRUSIVE_PTR_THROW(cond, type, msg) \
@@ -152,7 +176,9 @@ struct intrusive_ptr_error : virtual public std::exception { // from <exception
#elif defined INTRUSIVE_PTR_TRACING && INTRUSIVE_PTR_TRACING
#define INTRUSIVE_PTR_THROW(cond, type, msg) \
std::cerr << (msg) << "\n";
{ \
std::cerr << (msg) << "\n"; \
}
#elif defined INTRUSIVE_PTR_RUNTIME_CHECKS && INTRUSIVE_PTR_RUNTIME_CHECKS
#define INTRUSIVE_PTR_THROW(cond, type, msg) \
@@ -167,22 +193,22 @@ struct intrusive_ptr_error : virtual public std::exception { // from <exception
#endif
// Prints a message if tracing is enabled
/// \def INTRUSIVE_PTR_TRACING(msg)
/// Print a message to std::cerr if \ref INTRUSIVE_PTR_TRACING is 1.
#if defined INTRUSIVE_PTR_TRACING && INTRUSIVE_PTR_TRACING
#define INTRUSIVE_PTR_TRACE_MSG(msg) std::cerr << msg << "\n";
#define INTRUSIVE_PTR_TRACE_MSG(msg) { std::cerr << msg << "\n"; }
#else
#define INTRUSIVE_PTR_TRACE_MSG(msg) { }
#endif
// default policy for intrusive_ptr wrapped classes.
// the wrapped class MUST provide:
// inc_ref(), dec_ref(), ref_count().
/// Default threading policy for intrusive_ptr wrapped classes.
/// The wrapped class MUST provide: inc_ref(), dec_ref(), ref_count().
template<class PtrType>
struct IntrusivePtrRefFunctionsDefault {
/// Increase reference count
static int inc_ref(PtrType* p)
{
INTRUSIVE_PTR_THROW(!p, typeid(PtrType), "IntrusivePtrRefFunctionsDefault::inc_ref(): Error: NULL pointer passed!");
@@ -190,6 +216,7 @@ struct IntrusivePtrRefFunctionsDefault {
return p->inc_ref();
}
/// Decrease reference count
static int dec_ref(PtrType* p)
{
INTRUSIVE_PTR_THROW(!p, typeid(PtrType), "IntrusivePtrRefFunctionsDefault::dec_ref(): Error: NULL pointer passed!");
@@ -207,11 +234,12 @@ struct IntrusivePtrRefFunctionsDefault {
// If using intrusive_ptr_referenced_self_locked, this provides
// the default functions to use when locking the wrapped object.
/// If using intrusive_ptr_referenced_self_locked, this provides
/// the default functions to use when locking the wrapped object.
template<class Child>
struct IntrusivePtrChildLockFunctionsDefault {
/// Increase reference count
static void ref_lock(Child* p)
{
INTRUSIVE_PTR_THROW(!p, typeid(Child), "IntrusivePtrChildLockFunctionsDefault::ref_lock(): Error: NULL pointer passed!");
@@ -219,6 +247,7 @@ struct IntrusivePtrChildLockFunctionsDefault {
p->ref_lock();
}
/// Decrease reference count
static void ref_unlock(Child* p)
{
INTRUSIVE_PTR_THROW(!p, typeid(Child), "IntrusivePtrChildLockFunctionsDefault::ref_unlock(): Error: NULL pointer passed!");
@@ -230,55 +259,67 @@ struct IntrusivePtrChildLockFunctionsDefault {
// convenience class for subclassing, to provide intrusive_ptr support.
/// Convenience class to use as parent for user classes to provide
/// intrusive_ptr support (reference counting functions).
class intrusive_ptr_referenced {
public:
/// Constructor
intrusive_ptr_referenced() : ref_count_(0)
{ }
// Note: methods are const to allow construction of intrusive_ptr<const T>
// from const data while still incrementing the refcount.
/// Increase reference count
int inc_ref() const
{
return (++ref_count_);
}
/// Decrease reference count
int dec_ref() const
{
INTRUSIVE_PTR_THROW(ref_count_ <= 0, typeid(void), "intrusive_ptr_referenced::dec_ref(): ref_count <= 0 and decrease request received!");
return (--ref_count_);
}
/// Get reference count
int ref_count() const
{
return ref_count_;
}
protected:
mutable int ref_count_;
mutable int ref_count_; ///< Reference count
};
// same as above, but with locking multi-threading policy (mutex included).
/// Same as intrusive_ptr_referenced, but with locking multi-threading policy
/// (mutex included) for thread-safe reference counting.
template<class LockPolicy>
class intrusive_ptr_referenced_locked {
public:
typedef LockPolicy intrusive_ptr_lock_policy; // just in case
typedef typename LockPolicy::ScopedLock intrusive_ptr_scoped_lock_type;
typedef LockPolicy intrusive_ptr_lock_policy; ///< Locking policy
typedef typename LockPolicy::ScopedLock intrusive_ptr_scoped_lock_type; ///< Scoped lock type
/// Constructor
intrusive_ptr_referenced_locked() : ref_count_(0)
{ }
/// Increase reference count
int inc_ref() const
{
intrusive_ptr_scoped_lock_type locker(ref_mutex_);
return (++ref_count_);
}
/// Decrease reference count
int dec_ref() const
{
intrusive_ptr_scoped_lock_type locker(ref_mutex_);
@@ -286,32 +327,40 @@ class intrusive_ptr_referenced_locked {
return (--ref_count_);
}
/// Get reference count
int ref_count() const
{
intrusive_ptr_scoped_lock_type locker(ref_mutex_);
return ref_count_;
}
/// Get protecting mutex
typename LockPolicy::Mutex& get_ref_mutex()
{
return ref_mutex_;
}
protected:
mutable int ref_count_;
mutable typename LockPolicy::Mutex ref_mutex_;
mutable int ref_count_; ///< Reference count
mutable typename LockPolicy::Mutex ref_mutex_; ///< Protecting mutex
};
// same as above, but with locking functions and mutex inside the child class.
/// Same as intrusive_ptr_referenced_locked, but with locking functions and
/// mutex inside the child class. This is useful if the child already has them.
template<class Child, class LockFunctions = IntrusivePtrChildLockFunctionsDefault<Child> >
class intrusive_ptr_referenced_self_locked {
public:
/// Constructor
intrusive_ptr_referenced_self_locked() : ref_count_(0)
{ }
/// Increase reference count
int inc_ref() const
{
LockFunctions::ref_lock(static_cast<Child*>(this)); // this uses less memory than Locker.
@@ -320,6 +369,7 @@ class intrusive_ptr_referenced_self_locked {
return c;
}
/// Decrease reference count
int dec_ref() const
{
Locker locker(this); // we have to use this here because of its fuzzy scope
@@ -327,6 +377,7 @@ class intrusive_ptr_referenced_self_locked {
return (--ref_count_);
}
/// Get reference count
int ref_count() const
{
LockFunctions::ref_lock(static_cast<Child*>(this));
@@ -335,23 +386,29 @@ class intrusive_ptr_referenced_self_locked {
return c;
}
protected:
mutable int ref_count_;
mutable int ref_count_; /// Reference count
private:
/// Scoped locker object
struct Locker {
/// Constructor, locks \c self_
Locker(intrusive_ptr_referenced_self_locked* self_) : self(self_)
{
LockFunctions::ref_lock(static_cast<Child*>(self));
}
/// Destructor, unlocks \c self_
~Locker()
{
LockFunctions::ref_unlock(static_cast<Child*>(self));
}
intrusive_ptr_referenced_self_locked* self;
intrusive_ptr_referenced_self_locked* self; ///< An object to lock
};
};
@@ -359,24 +416,29 @@ class intrusive_ptr_referenced_self_locked {
// The actual smartpointer
/// Intrusive reference-counting smart pointer.
/// \tparam T Pointee type (without *).
/// \tparam RefFunctions Policy for reference counting
template<class T, class RefFunctions = IntrusivePtrRefFunctionsDefault<T> >
class intrusive_ptr {
private:
typedef intrusive_ptr<T, RefFunctions> this_type; // Borland-specific workaround
typedef intrusive_ptr<T, RefFunctions> this_type; ///< Borland-specific workaround
typedef T* this_type::*unspecified_bool_type;
typedef T* this_type::*unspecified_bool_type; ///< Helper type for if(p)-style casts.
public:
/// Wrapped type
typedef T element_type;
/// Constructor, creates a null pointer
intrusive_ptr() : p_(0)
{ }
/// Constructor. Note that the reference count of \c p is preserved
/// and possibly increased if \c add_ref is true.
intrusive_ptr(T* p, bool add_ref = true) : p_(p)
{
if (p_ != 0 && add_ref)
@@ -384,7 +446,8 @@ class intrusive_ptr {
}
// construct from other intrusive_ptr with implicitly-convertible pointer type
/// Construct from other intrusive_ptr with implicitly-convertible pointer type,
/// increases reference count.
template<class U, class R>
intrusive_ptr(const intrusive_ptr<U, R>& rhs) : p_(rhs.get())
{
@@ -393,6 +456,7 @@ class intrusive_ptr {
}
/// Copy constructor, increases reference count.
intrusive_ptr(const intrusive_ptr& rhs) : p_(rhs.p_)
{
if (p_ != 0)
@@ -400,6 +464,7 @@ class intrusive_ptr {
}
/// Destructor, decreases reference count.
~intrusive_ptr()
{
if (p_ != 0)
@@ -407,7 +472,8 @@ class intrusive_ptr {
}
/// Assignment operator from implicitly-convertible pointer type,
/// increases reference count.
template<class U, class R>
intrusive_ptr& operator=(const intrusive_ptr<U, R>& rhs)
{
@@ -416,13 +482,15 @@ class intrusive_ptr {
}
/// Assignment operator, increases reference count.
intrusive_ptr& operator=(const intrusive_ptr& rhs)
{
this_type(rhs).swap(*this);
return *this;
}
/// Assignment operator from plain pointer
intrusive_ptr& operator=(T* rhs)
{
this_type(rhs).swap(*this);
@@ -430,18 +498,23 @@ class intrusive_ptr {
}
/// Get the pointed object
T* get() const
{
return p_;
}
/// Dereference operator.
/// \throw intrusive_ptr_error if this is a null pointer.
T& operator*() const
{
INTRUSIVE_PTR_THROW(!p_, typeid(T), "intrusive_ptr::operator*(): Attempting to dereference NULL pointer!");
return *p_;
}
/// Arrow operator.
/// \throw intrusive_ptr_error if this is a null pointer.
T* operator->() const
{
INTRUSIVE_PTR_THROW(!p_, typeid(T), "intrusive_ptr::operator->(): Attempting to dereference NULL pointer!");
@@ -449,28 +522,21 @@ class intrusive_ptr {
}
/*
operator bool () const
{
return p_ != 0;
}
*/
// bool-like conversion
/// Bool-like conversion for null checks
operator unspecified_bool_type () const
{
return p_ == 0 ? 0 : &this_type::p_;
}
// operator! is a Borland-specific workaround
/// Operator! is a Borland-specific workaround
bool operator! () const
{
return p_ == 0;
}
/// Swap with other pointer
void swap(intrusive_ptr& rhs)
{
T* tmp = p_;
@@ -481,42 +547,48 @@ class intrusive_ptr {
private:
T* p_;
T* p_; ///< Pointed object
};
/// Comparison operator
template<class T, class R, class U, class S> inline
bool operator==(const intrusive_ptr<T, R>& a, const intrusive_ptr<U, S>& b)
{
return a.get() == b.get();
}
/// Comparison operator
template<class T, class R, class U, class S> inline
bool operator!=(const intrusive_ptr<T, R>& a, const intrusive_ptr<U, S>& b)
{
return a.get() != b.get();
}
/// Comparison operator
template<class T, class R, class U> inline
bool operator==(const intrusive_ptr<T, R>& a, U* b)
{
return a.get() == b;
}
/// Comparison operator
template<class T, class R, class U> inline
bool operator!=(const intrusive_ptr<T, R>& a, U* b)
{
return a.get() != b;
}
/// Comparison operator
template<class T, class U, class S> inline
bool operator==(T* a, const intrusive_ptr<U, S>& b)
{
return a == b.get();
}
/// Comparison operator
template<class T, class U, class S> inline
bool operator!=(T* a, const intrusive_ptr<U, S>& b)
{
@@ -524,6 +596,7 @@ bool operator!=(T* a, const intrusive_ptr<U, S>& b)
}
/// Comparison operator
template<class T, class R> inline
bool operator<(const intrusive_ptr<T, R>& a, const intrusive_ptr<T, R>& b)
{
@@ -531,14 +604,15 @@ bool operator<(const intrusive_ptr<T, R>& a, const intrusive_ptr<T, R>& b)
return a.get() < b.get();
}
/// Swap two pointers
template<class T, class R> inline
void swap(intrusive_ptr<T, R>& lhs, intrusive_ptr<T, R>& rhs)
{
lhs.swap(rhs);
}
// mem_fn support
/// Get pointed object. This is for mem_fn support.
template<class T, class R> inline
T* get_pointer(const intrusive_ptr<T, R>& p)
{
@@ -546,18 +620,21 @@ T* get_pointer(const intrusive_ptr<T, R>& p)
}
/// Perform a static cast on intrusive_ptr
template<class T, class R, class U> inline
intrusive_ptr<T, R> ptr_static_cast(const intrusive_ptr<U, R>& p)
{
return static_cast<T*>(p.get());
}
/// Perform a const cast on intrusive_ptr
template<class T, class U, class S> inline
intrusive_ptr<T> ptr_const_cast(const intrusive_ptr<U, S>& p) // return type's second parameter defaulted.
{
return const_cast<T*>(p.get());
}
/// Perform a const cast on intrusive_ptr
template<class T, class R, class U, class S> inline
intrusive_ptr<T, R> ptr_const_cast(const intrusive_ptr<U, S>& p)
{
@@ -567,6 +644,7 @@ intrusive_ptr<T, R> ptr_const_cast(const intrusive_ptr<U, S>& p)
#if !(defined DISABLE_RTTI && DISABLE_RTTI)
/// Perform a dynamic cast on intrusive_ptr
template<class T, class R, class U> inline
intrusive_ptr<T> ptr_dynamic_cast(const intrusive_ptr<U, R>& p)
{
@@ -597,3 +675,5 @@ std::ostream& operator<< (std::ostream& os, const intrusive_ptr<T, R>& p)
#endif
/// @}
+49 -35
View File
@@ -3,46 +3,35 @@
(C) 2008 - 2011 Alexander Shaduri <ashaduri 'at' gmail.com>
License: See LICENSE_zlib.txt
***************************************************************************/
/// \file
/// \author Alexander Shaduri
/// \ingroup hz
/// \weakgroup hz
/// @{
#ifndef HZ_INTRUSIVE_SCOPED_LOCK_H
#define HZ_INTRUSIVE_SCOPED_LOCK_H
#include "hz_config.h" // feature macros
/*
Intrusive scoped lock class.
The locking will be done by calling lock() and unlock()
methods of parameter object.
LockingPolicy template parameter may be used to control
which functions are called, as well as how.
Example usage:
{
SharedData* sd = get_some_shared_data(); // SharedData must have lock() and unlock().
intrusive_scoped_lock<SharedData*> locker(sd); // this will invoke sd->lock()
// at the end of the scope, sd->unlock() will be called.
}
*/
namespace hz {
// The template parameter class is expected to have
// lock() and unlock() functions.
/// Locking policy for intrusive_scoped_lock. The template parameter
/// class is expected to have lock() and unlock() functions.
template <class T>
struct IntrusiveLockingPolicyDefault {
/// Call obj.lock()
static void lock(T& obj)
{
obj.lock();
}
/// Call obj.unlock()
static void unlock(T& obj)
{
obj.unlock();
@@ -50,14 +39,16 @@ struct IntrusiveLockingPolicyDefault {
};
// specialization for pointers
/// Specialization for pointers
template <class T>
struct IntrusiveLockingPolicyDefault<T*> {
/// Call obj->lock()
static void lock(T obj)
{
obj->lock();
}
/// Call obj->unlock()
static void unlock(T obj)
{
obj->unlock();
@@ -66,17 +57,18 @@ struct IntrusiveLockingPolicyDefault<T*> {
// Same as above, but call the lock through "->", not ".".
// This allows its usage with smart pointers which transfer
// their locking to pointee objects.
/// Same as IntrusiveLockingPolicyDefault, but call the lock through
/// "->", not ".". This allows its usage with smart pointers which transfer
/// their locking to pointee objects.
template <class T>
struct IntrusiveLockingPolicySmart {
/// Call (&obj)->lock()
static void lock(T& obj)
{
(&obj)->lock();
}
/// Cal (&obj)->unlock()
static void unlock(T& obj)
{
(&obj)->unlock();
@@ -86,39 +78,59 @@ struct IntrusiveLockingPolicySmart {
// "don't do any actual locking" policy
/// Locking policy for intrusive_scoped_lock which does no locking at all.
template <class T>
struct IntrusiveLockingPolicyNone {
/// Do nothing
static void lock(T& obj)
{
}
{ }
/// Do nothing
static void unlock(T& obj)
{
}
{ }
};
/**
Intrusive scoped lock class. The locking is done by calling lock() and unlock()
methods of parameter object.
LockingPolicy template parameter may be used to control which functions
are called, as well as how.
Example usage:
\code
{
SharedData* sd = get_some_shared_data(); // SharedData must have lock() and unlock().
intrusive_scoped_lock<SharedData*> locker(sd); // this will invoke sd->lock()
// at the end of the scope, sd->unlock() will be called.
}
\endcode
*/
template <class T, class LockingPolicy = IntrusiveLockingPolicyDefault<T> >
class intrusive_scoped_lock {
public:
/// Constructor, locks the object. Note that the object is stored by reference
/// and therefore must exist as long as this object itself exists.
intrusive_scoped_lock(T& r, bool do_lock_ = true) : ref(r), do_lock(do_lock_)
{
if (do_lock)
LockingPolicy::lock(ref);
}
/// Destructor, unlocks the object.
~intrusive_scoped_lock()
{
if (do_lock)
LockingPolicy::unlock(ref);
}
/// Get the object we're operating with
T& get()
{
return ref;
@@ -127,16 +139,16 @@ class intrusive_scoped_lock {
private:
// disallow copying
// Private assignment operator (disallow copying)
intrusive_scoped_lock& operator=(const intrusive_scoped_lock&);
// Private copy constructor (disallow copying)
intrusive_scoped_lock(const intrusive_scoped_lock&);
T& ref;
T& ref; ///< The object we're operating with
bool do_lock;
bool do_lock; ///< If we're locking or not
};
@@ -150,3 +162,5 @@ class intrusive_scoped_lock {
#endif
/// @}
+13 -8
View File
@@ -3,6 +3,11 @@
(C) 2008 - 2011 Alexander Shaduri <ashaduri 'at' gmail.com>
License: See LICENSE_zlib.txt file
***************************************************************************/
/// \file
/// \author Alexander Shaduri
/// \ingroup hz
/// \weakgroup hz
/// @{
#ifndef HZ_LAUNCH_URL_H
#define HZ_LAUNCH_URL_H
@@ -26,17 +31,13 @@
// Note: Glib / GDK only.
// TODO: Use gtk_show_uri() if gtk 2.14.
namespace hz {
namespace internal {
/// Spawn the command (internal helper function)
inline bool launch_url_helper_do_launch(const std::string& command, GError** errorptr, GdkScreen* screen)
{
if (screen)
@@ -48,11 +49,13 @@ namespace hz {
// Open URL in browser or mailto: link in mail client.
// Return error message on error, empty string otherwise.
// The link is in utf-8 in windows.
/// Open URL in browser or mailto: link in mail client.
/// Return error message on error, empty string otherwise.
/// The link is in utf-8 in windows.
/// Note: This works using Glib / GDK only.
inline std::string launch_url(const std::string& link, GdkScreen* screen = 0)
{
// TODO: Use gtk_show_uri() if gtk 2.14.
if (link.empty())
return "Error while executing a command: Empty URI specified.";
@@ -141,3 +144,5 @@ namespace hz {
#endif
/// @}
+24 -15
View File
@@ -3,6 +3,11 @@
(C) 2008 - 2011 Alexander Shaduri <ashaduri 'at' gmail.com>
License: See LICENSE_zlib.txt file
***************************************************************************/
/// \file
/// \author Alexander Shaduri
/// \ingroup hz
/// \weakgroup hz
/// @{
#ifndef HZ_LOCAL_ALGO_H
#define HZ_LOCAL_ALGO_H
@@ -16,10 +21,11 @@
namespace hz {
// These standard-like algorithms are here to avoid including huge
// standard headers in a header-only library.
/**
\file
These standard-like algorithms are here to avoid including huge
standard headers in a header-only library.
*/
// -------------------------------- Shell Sort
@@ -27,12 +33,13 @@ namespace hz {
namespace internal {
// Helpers
/// Helper for shell_sort
template<class T>
struct shell_sort_helper { // works for operators
typedef typename T::value_type value_type;
};
/// Specialization
template<class T>
struct shell_sort_helper<T*> { // needed for C arrays
typedef T value_type;
@@ -42,10 +49,9 @@ namespace internal {
// Shell sort is one of the fastest on small datasets (<1000),
// and has a small memory footprint.
// Shell sort. Works for most STL containers.
/// Shell sort. Works for most STL containers.
/// Shell sort is one of the fastest on small datasets (<1000),
/// and has a small memory footprint.
template<class RandomIter> inline
void shell_sort(RandomIter first, RandomIter last)
{
@@ -64,7 +70,8 @@ void shell_sort(RandomIter first, RandomIter last)
}
// Same as above, but with custom comparator function
/// Same as the other shell_sort(), but with custom comparator function
template<class RandomIter, class Comparator> inline
void shell_sort(RandomIter first, RandomIter last, Comparator less_than_func)
{
@@ -84,11 +91,8 @@ void shell_sort(RandomIter first, RandomIter last, Comparator less_than_func)
// -------------------------------- Binary Search
/// Binary search.
/// \return iterator to found element, or \c end if not found.
template<typename RandomIter, typename ValueType> inline
RandomIter returning_binary_search(RandomIter begin, RandomIter end, const ValueType& value)
{
@@ -108,6 +112,9 @@ RandomIter returning_binary_search(RandomIter begin, RandomIter end, const Value
}
/// Binary search with custom comparator.
/// \return iterator to found element, or \c end if not found.
template<typename RandomIter, typename ValueType, typename LessComparator> inline
RandomIter returning_binary_search(RandomIter begin, RandomIter end,
const ValueType& value, LessComparator comp)
@@ -139,3 +146,5 @@ RandomIter returning_binary_search(RandomIter begin, RandomIter end,
#endif
/// @}
+75 -45
View File
@@ -3,6 +3,11 @@
(C) 2008 - 2011 Alexander Shaduri <ashaduri 'at' gmail.com>
License: See LICENSE_zlib.txt file
***************************************************************************/
/// \file
/// \author Alexander Shaduri
/// \ingroup hz
/// \weakgroup hz
/// @{
#ifndef HZ_LOCALE_TOOLS_H
#define HZ_LOCALE_TOOLS_H
@@ -18,16 +23,20 @@
namespace hz {
// NOTE: The POSIX man page for setlocale (which libstdc++ is based on)
// states: "The locale state is common to all threads within a process."
// This may have rather serious implications for thread-safety.
/**
\file
Locale manipulation facilities
// However, for glibc, libstdc++ uses the "uselocale" extension, which
// sets locale on per-thread basis.
Note: The POSIX man page for setlocale (which libstdc++ is based on)
states: "The locale state is common to all threads within a process."
This may have rather serious implications for thread-safety.
However, for glibc, libstdc++ uses the "uselocale" extension, which
sets locale on per-thread basis.
*/
// Set the C standard library locale
/// Set the C standard library locale, storing the previous one into \c old_locale.
/// \return false on failure
inline bool locale_c_set(const std::string& loc, std::string& old_locale)
{
// even though undocumented, glibc returns 0 when the locale string is invalid.
@@ -40,14 +49,17 @@ inline bool locale_c_set(const std::string& loc, std::string& old_locale)
}
// Set the C standard library locale
/// Set the C standard library locale.
/// \return false on failure
inline bool locale_c_set(const std::string& loc)
{
return std::setlocale(LC_ALL, loc.c_str()); // returns 0 if invalid
}
// Get current C standard library locale
/// Get current C standard library locale.
inline std::string locale_c_get()
{
return std::setlocale(LC_ALL, 0);
@@ -55,8 +67,9 @@ inline std::string locale_c_get()
// Set the C++ standard library locale (may also set the C locale)
/// Set the C++ standard library locale (may also set the C locale depending
/// on implementation), storing the previous one into \c old_locale.
/// \return false on failure (no exception is thrown)
inline bool locale_cpp_set(const std::locale& loc, std::locale& old_locale)
{
#if !(defined DISABLE_EXCEPTIONS && DISABLE_EXCEPTIONS)
@@ -77,7 +90,10 @@ inline bool locale_cpp_set(const std::locale& loc, std::locale& old_locale)
}
// Set the C++ standard library locale (may also set the C locale)
/// Set the C++ standard library locale (may also set the C locale depending
/// on implementation), storing the previous one's name into \c old_locale.
/// \return false on failure (no exception is thrown)
inline bool locale_cpp_set(const std::locale& loc, std::string& old_locale)
{
#if !(defined DISABLE_EXCEPTIONS && DISABLE_EXCEPTIONS)
@@ -94,7 +110,10 @@ inline bool locale_cpp_set(const std::locale& loc, std::string& old_locale)
}
// Set the C++ standard library locale (may also set the C locale)
/// Set the C++ standard library locale (may also set the C locale depending
/// on implementation).
/// \return false on failure (no exception is thrown)
inline bool locale_cpp_set(const std::locale& loc)
{
#if !(defined DISABLE_EXCEPTIONS && DISABLE_EXCEPTIONS)
@@ -112,8 +131,9 @@ inline bool locale_cpp_set(const std::locale& loc)
// Set the C++ standard library locale (may also set the C locale)
/// Set the C++ standard library locale name (may also set the C locale depending
/// on implementation), storing the previous one into \c old_locale.
/// \return false on failure (no exception is thrown)
inline bool locale_cpp_set(const std::string& loc, std::locale& old_locale)
{
#if !(defined DISABLE_EXCEPTIONS && DISABLE_EXCEPTIONS)
@@ -130,7 +150,9 @@ inline bool locale_cpp_set(const std::string& loc, std::locale& old_locale)
}
// Set the C++ standard library locale (may also set the C locale)
/// Set the C++ standard library locale name (may also set the C locale depending
/// on implementation), storing the previous one's name into \c old_locale.
/// \return false on failure (no exception is thrown)
inline bool locale_cpp_set(const std::string& loc, std::string& old_locale)
{
#if !(defined DISABLE_EXCEPTIONS && DISABLE_EXCEPTIONS)
@@ -147,7 +169,9 @@ inline bool locale_cpp_set(const std::string& loc, std::string& old_locale)
}
// Set the C++ standard library locale (may also set the C locale)
/// Set the C++ standard library locale name (may also set the C locale depending
/// on implementation).
/// \return false on failure (no exception is thrown)
inline bool locale_cpp_set(const std::string& loc)
{
#if !(defined DISABLE_EXCEPTIONS && DISABLE_EXCEPTIONS)
@@ -165,18 +189,22 @@ inline bool locale_cpp_set(const std::string& loc)
// Get current C++ standard library locale
/// Get current C++ standard library locale. This has no definition,
/// use one of the specializations.
template<typename ReturnType>
ReturnType locale_cpp_get(); // no definition - use the specializations below.
ReturnType locale_cpp_get();
/// Get current C++ standard library locale as a string.
/// May return "*" if it's not representable as a string.
template<> inline
std::string locale_cpp_get<std::string>()
{
return std::locale().name(); // may return "*" if it's not representable as a string
return std::locale().name();
}
/// Get current C++ standard library locale std::locale object.
template<> inline
std::locale locale_cpp_get<std::locale>()
{
@@ -187,14 +215,12 @@ std::locale locale_cpp_get<std::locale>()
// Temporarily change the C standard library locale
/// Temporarily change the C standard library locale as long
/// as this object lives.
class ScopedCLocale {
public:
// change to classic locale (aka "C")
/// Change to classic locale (aka "C")
ScopedCLocale(bool do_change = true) : do_change_(do_change), bad_(false)
{
if (do_change_) { // avoid unnecessary const char* -> string conversion overhead
@@ -202,7 +228,7 @@ class ScopedCLocale {
}
}
// change to user-specified locale loc.
/// Change to user-specified locale loc.
ScopedCLocale(const std::string& loc, bool do_change = true) : do_change_(do_change), bad_(false)
{
if (do_change_) {
@@ -210,25 +236,25 @@ class ScopedCLocale {
}
}
// change back
/// Change back the locale
~ScopedCLocale()
{
this->restore();
}
// get old locale
/// Get the old locale
std::string old() const
{
return old_locale_;
}
// Returns true if locale setting was unsuccessful
/// Return true if locale setting was unsuccessful
bool bad() const
{
return bad_;
}
// Restore the locale. Invoked by destructor.
/// Restore the locale. Invoked by destructor.
bool restore()
{
if (do_change_ && !bad_) {
@@ -240,20 +266,21 @@ class ScopedCLocale {
private:
std::string old_locale_;
bool do_change_;
bool bad_;
std::string old_locale_; ///< Old locale
bool do_change_; ///< Whether we changed something or not
bool bad_; ///< If true, there was some error
};
// Temporarily change the C++ standard library locale (may also set the C locale)
/// Temporarily change the C++ standard library locale, as long as this
/// object lives. This may also set the C locale depending on implementation.
class ScopedCppLocale {
public:
// change to classic locale (aka "C")
/// Change to classic locale (aka "C")
ScopedCppLocale(bool do_change = true) : do_change_(do_change), bad_(false)
{
if (do_change) {
@@ -261,7 +288,7 @@ class ScopedCppLocale {
}
}
// change to user-specified locale loc.
/// Change to user-specified locale loc.
ScopedCppLocale(const std::string& loc, bool do_change = true) : do_change_(do_change), bad_(false)
{
if (do_change_) {
@@ -269,7 +296,7 @@ class ScopedCppLocale {
}
}
// change to user-specified locale loc.
/// Change to user-specified locale loc.
ScopedCppLocale(const std::locale& loc, bool do_change = true) : do_change_(do_change), bad_(false)
{
if (do_change_) {
@@ -277,25 +304,25 @@ class ScopedCppLocale {
}
}
// change back
/// Change the locale back to the old one
~ScopedCppLocale()
{
this->restore();
}
// get old locale
/// Get the old locale
std::locale old() const
{
return old_locale_;
}
// Returns true if locale setting was unsuccessful
/// Return true if locale setting was unsuccessful
bool bad() const
{
return bad_;
}
// Restore the locale. Invoked by destructor.
/// Restore the locale. Invoked by destructor.
bool restore()
{
if (do_change_ && !bad_) {
@@ -307,9 +334,10 @@ class ScopedCppLocale {
private:
std::locale old_locale_;
bool do_change_;
bool bad_;
std::locale old_locale_; ///< The old locale
bool do_change_; ///< Whether we changed the locale or not
bool bad_; ///< If true, there was an error setting the locale
};
@@ -323,3 +351,5 @@ class ScopedCppLocale {
#endif
/// @}
+23 -13
View File
@@ -4,41 +4,49 @@
(C) 2008 - 2011 Alexander Shaduri <ashaduri 'at' gmail.com>
License: See LICENSE_boost_1_0.txt file
***************************************************************************/
/// \file
/// \author Dave Abrahams
/// \author Beman Dawes
/// \author Alexander Shaduri
/// \ingroup hz
/// \weakgroup hz
/// @{
#ifndef HZ_NONCOPYABLE_H
#define HZ_NONCOPYABLE_H
#include "hz_config.h" // feature macros
// Original notes and copyright info follow:
/**
\file
Original notes and copyright info follow:
Boost noncopyable.hpp header file
// Boost noncopyable.hpp header file --------------------------------------//
(C) Copyright Beman Dawes 1999-2003. Distributed under the Boost
Software License, Version 1.0. (See accompanying file
LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// (C) Copyright Beman Dawes 1999-2003. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/utility for documentation.
See http://www.boost.org/libs/utility for documentation.
*/
namespace hz {
// Private copy constructor and copy assignment ensure classes derived from
// class noncopyable cannot be copied.
// Contributed by Dave Abrahams
// namespace is for protection from unintended ADL
// (Argument-dependent lookup; this avoids unintended lookups in hz namespace).
/// This namespace is for protection from unintended ADL
/// (Argument-dependent lookup; this avoids unintended lookups in hz namespace).
namespace noncopyable_ {
/// Private copy constructor and copy assignment ensure classes derived from
/// class noncopyable cannot be copied.
class noncopyable {
protected:
noncopyable() {}
~noncopyable() {}
// ~noncopyable() {}
private: // emphasize the following members are private
noncopyable( const noncopyable& );
@@ -48,6 +56,7 @@ namespace hz {
}
/// Inherit this to make your objects non-copyable
typedef noncopyable_::noncopyable noncopyable;
@@ -58,3 +67,4 @@ namespace hz {
#endif
/// @}
+34 -12
View File
@@ -3,6 +3,11 @@
(C) 2009 - 2011 Alexander Shaduri <ashaduri 'at' gmail.com>
License: See LICENSE_zlib.txt file
***************************************************************************/
/// \file
/// \author Alexander Shaduri
/// \ingroup hz
/// \weakgroup hz
/// @{
#ifndef HZ_PORTABLE_SNPRINTF_H
#define HZ_PORTABLE_SNPRINTF_H
@@ -10,9 +15,17 @@
#include "hz_config.h" // feature macros
// Compilation options:
// - Define ENABLE_GLIB to 1 to enable glib-related code (portable ISO-compatible (v)snprintf).
/**
\file
Compilation options:
- Define \c ENABLE_GLIB to 1 to enable glib-related code (portable ISO-compatible (v)snprintf).
Keep in mind that these format types are non-portable (the first one is MS variant,
the second one is standard):
- %I64d, %lld (long long int),
- %I64u, %llu (unsigned long long int),
- %f, %Lf (long double; needs casting to double under non-ANSI mingw if using %f).
*/
namespace hz {
@@ -20,19 +33,22 @@ namespace hz {
// Note: There are macros, so they are not namespaced.
// portable_snprintf() and portable_vsnprintf() are snprintf() and vsnprintf()
// wrappers that always behave according to ISO standard in terms of 0-termination.
// There types are non-portable (the first one is MS variant, the second one is standard):
// %I64d, %lld (long long int),
// %I64u, %llu (unsigned long long int),
// %f, %Lf (long double; needs casting to double under non-ANSI mingw if using %f).
/// \def HAVE_PORTABLE_SNPRINTF_MS
/// If 1, portable_snprintf() and portable_vsnprintf() accept I64d, I64u.
/// Users are expected to check this macro to see if the format is supported.
// HAVE_PORTABLE_SNPRINTF_MS - portable_snprintf() accepts I64d, I64u.
// HAVE_PORTABLE_SNPRINTF_ISO - portable_snprintf() accepts lld, llu, Lf.
/// \def HAVE_PORTABLE_SNPRINTF_ISO
/// If 1, portable_snprintf() and portable_vsnprintf() accept lld, llu, Lf.
/// Users are expected to check this macro to see if the format is supported.
// Usage: void portable_snprintf(char *str, size_t size, const char *format, ...);
/// \def portable_snprintf(buf, buf_size, ...)
/// snprintf() wrapper that always behaves according to ISO standard in terms of 0-termination.
/// Note that this is a macro, and therefore not namespaced.
/// Use it like this:
/// \code void portable_snprintf(char *str, size_t size, const char *format, ...); \endcode
#if defined ENABLE_GLIB && ENABLE_GLIB
#include <glib.h> // g_snprintf
@@ -96,7 +112,11 @@ namespace hz {
// Usage: void portable_vsnprintf(char *str, size_t size, const char *format, va_list ap);
/// \def portable_vsnprintf(buf, buf_size, ...)
/// vsnprintf() wrapper that always behaves according to ISO standard in terms of 0-termination.
/// Note that this is a macro, and therefore not namespaced.
/// Use it like this:
/// \code void portable_vsnprintf(char *str, size_t size, const char *format, va_list ap); \endcode
#if defined ENABLE_GLIB && ENABLE_GLIB
#include <glib.h> // g_vsnprintf
@@ -171,3 +191,5 @@ namespace hz {
#endif
/// @}
+41 -21
View File
@@ -3,6 +3,11 @@
(C) 2008 - 2011 Alexander Shaduri <ashaduri 'at' gmail.com>
License: See LICENSE_zlib.txt file
***************************************************************************/
/// \file
/// \author Alexander Shaduri
/// \ingroup hz
/// \weakgroup hz
/// @{
#ifndef HZ_PROCESS_SIGNAL_H
#define HZ_PROCESS_SIGNAL_H
@@ -34,9 +39,11 @@
// Compilation options:
// Define ENABLE_GLIB to 1 to enable glib-related code (portable signal messages).
/**
\file
Compilation options:
- Define ENABLE_GLIB to 1 to enable glib-related code (portable signal messages).
*/
// win32 doesn't have signal W* macros, define them (this is _very_ rough,
@@ -55,39 +62,53 @@
namespace hz {
// Note: This function may return messages in native language,
// possibly using LC_MESSAGES to select the language.
// If Glib is enabled, it returns messages in UTF-8 format.
// portable strsignal() version for std::string.
/// Portable strsignal() version for std::string.
/// Note: This function may return messages in native language,
/// possibly using LC_MESSAGES to select the language.
/// If Glib is enabled, it returns messages in UTF-8 format.
inline std::string signal_string(int signal_value);
/// \typedef process_id_t
/// Process handle
/// \enum signal_t
/// Sendable signals
/// \var signal_t SIGNAL_SIGNONE
/// Verify that the process exists
/// \var signal_t SIGNAL_SIGTERM
/// Ask the process to terminate itself
/// \var signal_t SIGNAL_SIGKILL
/// Nuke the process
#ifdef _WIN32
typedef HANDLE process_id_t; // process handle, not process id
enum signal_t { // sendable signals
SIGNAL_SIGNONE, // verify that process exists
SIGNAL_SIGTERM, // ask to terminate
SIGNAL_SIGKILL // nuke
enum signal_t {
SIGNAL_SIGNONE,
SIGNAL_SIGTERM,
SIGNAL_SIGKILL
};
#else
typedef pid_t process_id_t;
enum signal_t { // sendable signals
SIGNAL_SIGNONE = 0, // verify that process exists
SIGNAL_SIGTERM = SIGTERM, // ask to terminate
SIGNAL_SIGKILL = SIGKILL // nuke
enum signal_t {
SIGNAL_SIGNONE = 0,
SIGNAL_SIGTERM = SIGTERM,
SIGNAL_SIGKILL = SIGKILL
};
#endif
// Portable kill(). Works with signal_t signals only.
// Process groups are not supported under win32.
/// Portable kill(). Works with signal_t signals only.
/// Process groups are not supported under win32.
inline int process_signal_send(process_id_t process_handle, signal_t sig);
@@ -97,7 +118,6 @@ inline int process_signal_send(process_id_t process_handle, signal_t sig);
// portable strsignal() version for std::string.
inline std::string signal_to_string(int signal_value)
{
std::string msg;
@@ -173,8 +193,6 @@ namespace internal {
#else
// Works with signal_t signals only.
// Process groups are not supported under win32.
inline int process_signal_send(process_id_t process_handle, signal_t sig)
{
if (process_handle <= 0) {
@@ -276,3 +294,5 @@ namespace internal {
#endif
/// @}
+59 -39
View File
@@ -3,6 +3,12 @@
(C) 2008 - 2011 Alexander Shaduri <ashaduri 'at' gmail.com>
License: See LICENSE_zlib.txt file
***************************************************************************/
/// \file
/// \author Yonat Sharon
/// \author Alexander Shaduri
/// \ingroup hz
/// \weakgroup hz
/// @{
#ifndef HZ_PTR_CONTAINER_H
#define HZ_PTR_CONTAINER_H
@@ -11,15 +17,19 @@
#include "type_properties.h"
/*
namespace hz {
/**
A pointer-container wrapper class which auto-deletes its elements.
Heavily based on ptr_container class by Yonat Sharon <yonat 'at' ootips.org>,
from http://ootips.org/yonat/4dev/ .
*/
/*
// Example usage:
Example usage:
\code
{
ptr_container<std::vector<int*> > v;
// v can be manipulated like any std::vector<int*>.
@@ -32,55 +42,52 @@ from http://ootips.org/yonat/4dev/ .
// frees the memory allocated for the int 42, and then removes the
// first element of v.
}
// v's destructor is called, and it frees the memory allocated for
// the int 17.
// v's destructor is called, and it frees the memory allocated for the int 17.
\endcode
Notes:
1. Assumes that all elements are unique (you don't have two elements
pointing to the same object, otherwise you might delete it twice).
2. Not usable with pair associative containers (map and multimap).
*/
namespace hz {
template<typename Container>
class ptr_container : public Container {
public:
// parent's stuff
typedef typename Container::size_type size_type;
typedef typename Container::difference_type difference_type;
typedef typename Container::reference reference;
typedef typename Container::const_reference const_reference;
typedef typename Container::value_type value_type;
typedef typename Container::iterator iterator;
typedef typename Container::const_iterator const_iterator;
typedef typename Container::reverse_iterator reverse_iterator;
typedef typename Container::const_reverse_iterator const_reverse_iterator;
typedef typename Container::size_type size_type; ///< STL compatibility
typedef typename Container::difference_type difference_type; ///< STL compatibility
typedef typename Container::reference reference; ///< STL compatibility
typedef typename Container::const_reference const_reference; ///< STL compatibility
typedef typename Container::value_type value_type; ///< STL compatibility
typedef typename Container::iterator iterator; ///< STL compatibility
typedef typename Container::const_iterator const_iterator; ///< STL compatibility
typedef typename Container::reverse_iterator reverse_iterator; ///< STL compatibility
typedef typename Container::const_reverse_iterator const_reverse_iterator; ///< STL compatibility
typedef ptr_container<Container> self_type;
typedef Container wrapped_type;
typedef ptr_container<Container> self_type; ///< Type of this class
typedef Container wrapped_type; ///< Wrapped container type
using Container::begin;
using Container::end;
using Container::size;
/// Constructor
ptr_container()
{ }
/// Construct from existing container
ptr_container(const Container& c) : Container(c)
{ }
/// Destructor, deletes all elements
~ptr_container()
{
clean_all();
}
/// Assignment operator (from existing container)
self_type& operator= (const Container& c)
{
Container::operator=(c);
@@ -90,52 +97,55 @@ class ptr_container : public Container {
private:
// disallow copying of this container, because it the pointers will be copied
// to and then double-deleted.
/// Private copy constructor (disallows copying and therefore double-deletion)
ptr_container(const self_type&);
ptr_container(const self_type&); // private copy constructor
self_type& operator= (const self_type&); // private assignment operator
/// Private assignment operator (disallows copying and therefore double-deletion)
self_type& operator= (const self_type&);
public:
/// Delete all elements, clear the container
void clear()
{
clean_all(); // delete pointers
Container::clear(); // clear the container
}
/// Delete one element, remove it from container
iterator erase(iterator i)
{
clean(i);
return Container::erase(i);
}
/// Delete a range of elements, remove them from container
iterator erase(iterator f, iterator l)
{
clean(f,l);
return Container::erase(f,l);
}
// for associative containers: erase() a value
/// For associative containers: erase() a value
size_type erase(const value_type& v)
{
iterator i = find(v);
iterator i = Container::find(v);
size_type found(i != end()); // can't have more than 1
if (found)
erase(i);
return found;
}
// for sequence containers: pop_front(), pop_back(), resize() and assign()
/// Delete the first element, remove it from container.
void pop_front()
{
clean(begin());
Container::pop_front();
}
/// Delete the last element, remove it from container.
void pop_back()
{
iterator i(end());
@@ -143,6 +153,8 @@ class ptr_container : public Container {
Container::pop_back();
}
/// Resize the container. If the new size is smaller than the current
/// one, delete the extra elements and remove them.
void resize(size_type s, value_type c = value_type())
{
if (s < size())
@@ -150,6 +162,7 @@ class ptr_container : public Container {
Container::resize(s, c);
}
/// Clear the container (deleting everything) and assign a new range to it.
template <class InputIterator>
void assign(InputIterator first, InputIterator last)
{
@@ -157,6 +170,7 @@ class ptr_container : public Container {
Container::assign(first, last);
}
/// Clear the container (deleting everything) and create a range of \c n elements.
template <class Size, class T>
void assign(Size n, const T& t = T())
{
@@ -164,7 +178,7 @@ class ptr_container : public Container {
Container::assign(n, t);
}
// for std::list: remove() and remove_if()
/// For std::list: remove by value (delete if found)
void remove(const value_type& v)
{
for (iterator i = begin(); i != end(); ++i) {
@@ -177,6 +191,7 @@ class ptr_container : public Container {
Container::remove(v);
}
/// For std::list: remove by predicate (delete if found)
template <class Pred>
void remove_if(Pred pr)
{
@@ -191,9 +206,10 @@ class ptr_container : public Container {
// Additional, non-Container-emulating functions:
// You MUST delete the elements of put_here.
/// Deep-clone the container and its elements.
/// You MUST delete the elements of \c put_here after you're done with them.
template<class ReturnedContainer>
void clone_to(ReturnedContainer& put_here) const // deep-clone
void clone_to(ReturnedContainer& put_here) const
{
put_here.assign(this->begin(), this->end());
for (typename ReturnedContainer::iterator i = put_here.begin(); i != put_here.end(); ++i) {
@@ -201,9 +217,9 @@ class ptr_container : public Container {
}
}
// You MUST delete the elements of put_here.
// Same as above, but calls the clone() method of object-to clone.
// This is needed if we hold the base pointers of child classes.
/// Same as clone_to(), but calls the clone() method of objects-to clone.
/// This is needed if we hold the base pointers of child classes.
/// You MUST delete the elements of put_here.
template<class ReturnedContainer>
void clone_by_method_to(ReturnedContainer& put_here) const // deep-clone
{
@@ -214,20 +230,22 @@ class ptr_container : public Container {
}
private:
/// Delete element
void clean(iterator i)
{
delete *i;
}
/// Delete range
void clean(iterator first, iterator last)
{
while (first != last)
clean(first++);
}
/// Delete all elements
void clean_all()
{
clean(begin(), end());
@@ -243,3 +261,5 @@ class ptr_container : public Container {
#endif
/// @}
+7
View File
@@ -3,6 +3,11 @@
(C) 2008 - 2011 Alexander Shaduri <ashaduri 'at' gmail.com>
License: See LICENSE_zlib.txt file
***************************************************************************/
/// \file
/// \author Alexander Shaduri
/// \ingroup hz
/// \weakgroup hz
/// @{
#ifndef HZ_RES_DATA_H
#define HZ_RES_DATA_H
@@ -152,3 +157,5 @@
#endif
/// @}