mirror of
https://github.com/ashaduri/gsmartcontrol.git
synced 2026-09-25 21:35:33 +00:00
Documented some more of hz.
This commit is contained in:
@@ -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
|
||||
|
||||
/// @}
|
||||
|
||||
@@ -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
|
||||
|
||||
/// @}
|
||||
|
||||
@@ -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
|
||||
|
||||
/// @}
|
||||
|
||||
@@ -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
|
||||
|
||||
/// @}
|
||||
|
||||
@@ -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
|
||||
|
||||
/// @}
|
||||
|
||||
@@ -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
|
||||
|
||||
/// @}
|
||||
|
||||
@@ -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
|
||||
|
||||
/// @}
|
||||
|
||||
@@ -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
|
||||
|
||||
/// @}
|
||||
|
||||
@@ -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
|
||||
|
||||
/// @}
|
||||
|
||||
@@ -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
|
||||
|
||||
/// @}
|
||||
|
||||
@@ -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
|
||||
|
||||
/// @}
|
||||
|
||||
Reference in New Issue
Block a user