added QSE_CPP_RVREF.
enhanced Array and BinaryHeap for C++11
This commit is contained in:
@ -31,8 +31,7 @@
|
||||
/// \file
|
||||
/// Provides the Exception class.
|
||||
|
||||
#include <qse/types.h>
|
||||
#include <qse/macros.h>
|
||||
#include <qse/Types.hpp>
|
||||
|
||||
/////////////////////////////////
|
||||
QSE_BEGIN_NAMESPACE(QSE)
|
||||
|
@ -30,8 +30,7 @@
|
||||
/// \file
|
||||
/// Provides classes for handling size growth including buffer growth.
|
||||
|
||||
#include <qse/types.h>
|
||||
#include <qse/macros.h>
|
||||
#include <qse/Types.hpp>
|
||||
|
||||
/////////////////////////////////
|
||||
QSE_BEGIN_NAMESPACE(QSE)
|
||||
|
@ -30,8 +30,7 @@
|
||||
/// \file
|
||||
/// Privides the Hashable interface class.
|
||||
|
||||
#include <qse/types.h>
|
||||
#include <qse/macros.h>
|
||||
#include <qse/Types.hpp>
|
||||
|
||||
/////////////////////////////////
|
||||
QSE_BEGIN_NAMESPACE(QSE)
|
||||
|
@ -27,11 +27,43 @@
|
||||
#ifndef _QSE_TYPES_HPP_
|
||||
#define _QSE_TYPES_HPP_
|
||||
|
||||
/// \file
|
||||
/// Defines aliases to various QSE types in a class and holds various feature
|
||||
/// configuration options.
|
||||
|
||||
#include <qse/types.h>
|
||||
#include <qse/macros.h>
|
||||
|
||||
/// \file
|
||||
/// Defines a class containg aliases to various QSE types.
|
||||
/// The QSE_ENABLE_CPP11_MOVE macro enables C++11 move semantics
|
||||
/// in various classes.
|
||||
#if (__cplusplus >= 201103L) // C++11
|
||||
# define QSE_ENABLE_CPP11_MOVE 1
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(QSE_ENABLE_CPP11_MOVE)
|
||||
|
||||
template<typename T> struct QSE_CPP_RMREF { typedef T Type;} ;
|
||||
template<typename T> struct QSE_CPP_RMREF<T&> { typedef T Type; };
|
||||
template<typename T> struct QSE_CPP_RMREF<T&&> { typedef T Type; };
|
||||
|
||||
template<typename T> inline
|
||||
typename QSE_CPP_RMREF<T>::Type&& QSE_CPP_RVREF(T&& v)
|
||||
{
|
||||
return (typename QSE_CPP_RMREF<T>::Type&&)v;
|
||||
}
|
||||
#else
|
||||
|
||||
/*
|
||||
template<typename T> inline
|
||||
T& QSE_CPP_RVREF(T& v) { return (T&)v; }
|
||||
|
||||
template<typename T> inline
|
||||
const T& QSE_CPP_RVREF(const T& v) { return (const T&)v; }
|
||||
*/
|
||||
#define QSE_CPP_RVREF(x) x
|
||||
#endif
|
||||
|
||||
|
||||
/////////////////////////////////
|
||||
QSE_BEGIN_NAMESPACE(QSE)
|
||||
|
@ -30,8 +30,7 @@
|
||||
/// \file
|
||||
/// Provides the Uncopyable class.
|
||||
|
||||
#include <qse/types.h>
|
||||
#include <qse/macros.h>
|
||||
#include <qse/Types.hpp>
|
||||
|
||||
/////////////////////////////////
|
||||
QSE_BEGIN_NAMESPACE(QSE)
|
||||
|
@ -122,7 +122,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
#if (__cplusplus >= 201103L) // C++11
|
||||
#if defined(QSE_ENABLE_CPP11_MOVE)
|
||||
|
||||
Array (SelfType&& array):
|
||||
Mmged(array.getMmgr()),
|
||||
@ -162,7 +162,7 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if (__cplusplus >= 201103L) // C++11
|
||||
#if defined(QSE_ENABLE_CPP11_MOVE)
|
||||
SelfType& operator= (SelfType&& array)
|
||||
{
|
||||
if (this != &array)
|
||||
@ -227,7 +227,7 @@ protected:
|
||||
return tmp;
|
||||
}
|
||||
|
||||
#if (__cplusplus >= 201103L) // C++11
|
||||
#if defined(QSE_ENABLE_CPP11_MOVE)
|
||||
T* clone_buffer_by_moving (T* srcbuf, qse_size_t capa, qse_size_t cnt)
|
||||
{
|
||||
QSE_ASSERT (capa > 0);
|
||||
@ -292,7 +292,7 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
#if (__cplusplus >= 201103L) // C++11
|
||||
#if defined(QSE_ENABLE_CPP11_MOVE)
|
||||
void put_item_by_moving (qse_size_t index, T&& value)
|
||||
{
|
||||
if (index >= this->count)
|
||||
@ -418,6 +418,13 @@ public:
|
||||
this->update (index, value);
|
||||
}
|
||||
|
||||
#if defined(QSE_ENABLE_CPP11_MOVE)
|
||||
void setValueAt (qse_size_t index, T&& value)
|
||||
{
|
||||
this->update (index, (T&&)value);
|
||||
}
|
||||
#endif
|
||||
|
||||
protected:
|
||||
void secure_slot (qse_size_t index)
|
||||
{
|
||||
@ -445,7 +452,7 @@ protected:
|
||||
// shift the existing elements to the back by one slot.
|
||||
for (qse_size_t i = this->count; i > index; i--)
|
||||
{
|
||||
#if (__cplusplus >= 201103L) // C++11
|
||||
#if defined(QSE_ENABLE_CPP11_MOVE)
|
||||
this->put_item_by_moving (i, (T&&)this->buffer[i - 1]);
|
||||
#else
|
||||
this->put_item (i, this->buffer[i - 1]);
|
||||
@ -482,7 +489,7 @@ public:
|
||||
return index;
|
||||
}
|
||||
|
||||
#if (__cplusplus >= 201103L) // C++11
|
||||
#if defined(QSE_ENABLE_CPP11_MOVE)
|
||||
qse_size_t insert (qse_size_t index, T&& value)
|
||||
{
|
||||
// Unlike insert() in RedBlackTree and HashList,
|
||||
@ -509,7 +516,7 @@ public:
|
||||
return index;
|
||||
}
|
||||
|
||||
#if (__cplusplus >= 201103L) // C++11
|
||||
#if defined(QSE_ENABLE_CPP11_MOVE)
|
||||
qse_size_t update (qse_size_t index, T&& value)
|
||||
{
|
||||
QSE_ASSERT (index < this->count);
|
||||
@ -527,7 +534,7 @@ public:
|
||||
return this->insert (index, value);
|
||||
}
|
||||
|
||||
#if (__cplusplus >= 201103L) // C++11
|
||||
#if defined(QSE_ENABLE_CPP11_MOVE)
|
||||
qse_size_t upsert (qse_size_t index, T&& value)
|
||||
{
|
||||
if (index < this->count)
|
||||
@ -545,7 +552,7 @@ public:
|
||||
return this->insert (index, value);
|
||||
}
|
||||
|
||||
#if (__cplusplus >= 201103L) // C++11
|
||||
#if defined(QSE_ENABLE_CPP11_MOVE)
|
||||
qse_size_t ensert (qse_size_t index, T&& value)
|
||||
{
|
||||
if (index < this->count)
|
||||
@ -584,7 +591,7 @@ public:
|
||||
//this->_positioner (this->buffer[j], j);
|
||||
|
||||
// 2. operator assignment
|
||||
#if (__cplusplus >= 201103L) // C++11
|
||||
#if defined(QSE_ENABLE_CPP11_MOVE)
|
||||
this->buffer[j] = (T&&)this->buffer[i];
|
||||
#else
|
||||
this->buffer[j] = this->buffer[i];
|
||||
@ -684,7 +691,7 @@ public:
|
||||
qse_size_t cnt = this->count;
|
||||
if (cnt > capa) cnt = capa;
|
||||
|
||||
#if (__cplusplus >= 201103L) // C++11
|
||||
#if defined(QSE_ENABLE_CPP11_MOVE)
|
||||
T* tmp = this->clone_buffer_by_moving (this->buffer, capa, cnt);
|
||||
#else
|
||||
T* tmp = this->clone_buffer (this->buffer, capa, cnt);
|
||||
@ -748,39 +755,61 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
void rotate (int dir, qse_size_t n)
|
||||
enum RotateDirection
|
||||
{
|
||||
ROTATE_LEFT,
|
||||
ROTATE_RIGHT
|
||||
};
|
||||
|
||||
void rotate (RotateDirection dir, qse_size_t n)
|
||||
{
|
||||
qse_size_t first, last, cnt, index, nk;
|
||||
T c;
|
||||
|
||||
if (dir == 0) return;
|
||||
if ((n %= this->count) == 0) return;
|
||||
|
||||
if (dir > 0) n = this->count - n;
|
||||
if (dir == ROTATE_RIGHT) n = this->count - n;
|
||||
first = 0; nk = this->count - n; cnt = 0;
|
||||
|
||||
while (cnt < n)
|
||||
{
|
||||
last = first + nk;
|
||||
index = first;
|
||||
c = this->buffer[first];
|
||||
#if defined(QSE_ENABLE_CPP11_MOVE)
|
||||
c = (T&&)this->buffer[index];
|
||||
#else
|
||||
c = this->buffer[index];
|
||||
#endif
|
||||
while (1)
|
||||
{
|
||||
cnt++;
|
||||
while (index < nk)
|
||||
{
|
||||
#if defined(QSE_ENABLE_CPP11_MOVE)
|
||||
this->buffer[index] = (T&&)this->buffer[index + n];
|
||||
#else
|
||||
this->buffer[index] = this->buffer[index + n];
|
||||
#endif
|
||||
this->_positioner (this->buffer[index], index);
|
||||
index += n;
|
||||
}
|
||||
if (index == last) break;
|
||||
|
||||
#if defined(QSE_ENABLE_CPP11_MOVE)
|
||||
this->buffer[index] = (T&&)this->buffer[index - nk];
|
||||
#else
|
||||
this->buffer[index] = this->buffer[index - nk];
|
||||
#endif
|
||||
this->_positioner (this->buffer[index], index);
|
||||
index -= nk;
|
||||
}
|
||||
|
||||
|
||||
#if defined(QSE_ENABLE_CPP11_MOVE)
|
||||
this->buffer[last] = (T&&)c;
|
||||
#else
|
||||
this->buffer[last] = c;
|
||||
#endif
|
||||
this->_positioner (this->buffer[last], last);
|
||||
first++;
|
||||
}
|
||||
|
@ -27,8 +27,7 @@
|
||||
#ifndef _QSE_CMN_ASSOCIATION_HPP_
|
||||
#define _QSE_CMN_ASSOCIATION_HPP_
|
||||
|
||||
#include <qse/types.h>
|
||||
#include <qse/macros.h>
|
||||
#include <qse/Types.hpp>
|
||||
|
||||
/////////////////////////////////
|
||||
QSE_BEGIN_NAMESPACE(QSE)
|
||||
|
@ -135,7 +135,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
#if (__cplusplus >= 201103L) // C++11
|
||||
#if defined(QSE_ENABLE_CPP11_MOVE)
|
||||
BinaryHeap (SelfType& heap): ParentType (heap)
|
||||
{
|
||||
}
|
||||
@ -154,7 +154,7 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if (__cplusplus >= 201103L) // C++11
|
||||
#if defined(QSE_ENABLE_CPP11_MOVE)
|
||||
SelfType& operator= (SelfType&& heap)
|
||||
{
|
||||
if (this != &heap)
|
||||
@ -212,13 +212,13 @@ public:
|
||||
return this->sift_up(index);
|
||||
}
|
||||
|
||||
#if (__cplusplus >= 201103L) // C++11
|
||||
#if defined(QSE_ENABLE_CPP11_MOVE)
|
||||
qse_size_t insert (T&& value)
|
||||
{
|
||||
qse_size_t index = this->count;
|
||||
|
||||
// add the item at the back of the array
|
||||
ParentType::insert (index, (T&&)value);
|
||||
ParentType::insert (index, QSE_CPP_RVREF(value));
|
||||
|
||||
// move the item up to the top if it's greater than the up item
|
||||
return this->sift_up(index);
|
||||
@ -230,19 +230,15 @@ public:
|
||||
qse_size_t update (qse_size_t index, const T& value)
|
||||
{
|
||||
T old = this->buffer[index];
|
||||
|
||||
ParentType::update (index, value);
|
||||
|
||||
return (this->greater_than(value, old))? this->sift_up(index): this->sift_down(index);
|
||||
}
|
||||
|
||||
#if (__cplusplus >= 201103L) // C++11
|
||||
#if defined(QSE_ENABLE_CPP11_MOVE)
|
||||
qse_size_t update (qse_size_t index, T&& value)
|
||||
{
|
||||
T old = this->buffer[index];
|
||||
|
||||
ParentType::update (index, (T&&)value);
|
||||
|
||||
T old = QSE_CPP_RVREF(this->buffer[index]);
|
||||
ParentType::update (index, QSE_CPP_RVREF(value));
|
||||
return (this->greater_than(value, old))? this->sift_up(index): this->sift_down(index);
|
||||
}
|
||||
#endif
|
||||
@ -252,19 +248,25 @@ public:
|
||||
{
|
||||
QSE_ASSERT (index < this->count);
|
||||
|
||||
// TODO: move semantics herr
|
||||
//BEGIN
|
||||
// copy the last item to the position to remove
|
||||
T old = this->buffer[index];
|
||||
if (this->count == 1)
|
||||
{
|
||||
QSE_ASSERT (index == 0);
|
||||
ParentType::remove (this->count - 1);
|
||||
}
|
||||
else if (this->count > 1)
|
||||
{
|
||||
// store the item to remove temporarily
|
||||
T old = QSE_CPP_RVREF(this->buffer[index]);
|
||||
|
||||
ParentType::update (index, this->buffer[this->count - 1]);
|
||||
// END..
|
||||
// copy the last item to the position to remove
|
||||
ParentType::update (index, QSE_CPP_RVREF(this->buffer[this->count - 1]));
|
||||
|
||||
// delete the last item
|
||||
ParentType::remove (this->count - 1);
|
||||
|
||||
// relocate the item
|
||||
(this->greater_than (this->buffer[index], old))? this->sift_up(index): this->sift_down(index);
|
||||
// delete the last item
|
||||
ParentType::remove (this->count - 1);
|
||||
|
||||
// relocate the item
|
||||
(this->greater_than (this->buffer[index], old))? this->sift_up(index): this->sift_down(index);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
@ -275,18 +277,18 @@ protected:
|
||||
up = QSE_BINARY_HEAP_UP(index);
|
||||
if (index > 0 && this->greater_than(this->buffer[index], this->buffer[up]))
|
||||
{
|
||||
T item = this->buffer[index];
|
||||
T item = QSE_CPP_RVREF(this->buffer[index]);
|
||||
|
||||
do
|
||||
{
|
||||
ParentType::setValueAt (index, this->buffer[up]);
|
||||
ParentType::setValueAt (index, QSE_CPP_RVREF(this->buffer[up]));
|
||||
|
||||
index = up;
|
||||
up = QSE_BINARY_HEAP_UP(up);
|
||||
}
|
||||
while (index > 0 && this->greater_than(item, this->buffer[up]));
|
||||
|
||||
ParentType::setValueAt (index, item);
|
||||
ParentType::setValueAt (index, QSE_CPP_RVREF(item));
|
||||
}
|
||||
|
||||
return index;
|
||||
@ -301,15 +303,15 @@ protected:
|
||||
// if at least 1 child is under the 'index' position
|
||||
// perform sifting
|
||||
|
||||
T item = this->buffer[index];
|
||||
T item = QSE_CPP_RVREF(this->buffer[index]);
|
||||
|
||||
do
|
||||
{
|
||||
qse_size_t left, right, greater;
|
||||
|
||||
|
||||
left = QSE_BINARY_HEAP_LEFT(index);
|
||||
right = QSE_BINARY_HEAP_RIGHT(index);
|
||||
|
||||
|
||||
// choose the larger one between 2 BinaryHeap
|
||||
if (right < this->count &&
|
||||
this->greater_than(this->buffer[right], this->buffer[left]))
|
||||
@ -325,12 +327,12 @@ protected:
|
||||
|
||||
if (this->greater_than(item, this->buffer[greater])) break;
|
||||
|
||||
ParentType::setValueAt (index, this->buffer[greater]);
|
||||
ParentType::setValueAt (index, QSE_CPP_RVREF(this->buffer[greater]));
|
||||
index = greater;
|
||||
}
|
||||
while (index < half_data_count);
|
||||
|
||||
ParentType::setValueAt (index, item);
|
||||
ParentType::setValueAt (index, QSE_CPP_RVREF(item));
|
||||
}
|
||||
|
||||
return index;
|
||||
|
@ -764,8 +764,14 @@ private:
|
||||
{
|
||||
// destruction in response to 'placement new'
|
||||
|
||||
// call the destructor
|
||||
this->datum_list->~DatumList();
|
||||
#if defined(__BORLANDC__)
|
||||
// BCC55 doesn't support the explicit destructor call.
|
||||
// instead, call shatter() which is actually called by ~DatumList().
|
||||
this->datum_list->shatter ();
|
||||
#else
|
||||
// call the destructor for completeness
|
||||
this->datum_list->~DatumList ();
|
||||
#endif
|
||||
// free the memory
|
||||
::operator delete (this->datum_list, this->getMmgr());
|
||||
}
|
||||
|
@ -207,6 +207,11 @@ public:
|
||||
};
|
||||
|
||||
~LinkedList ()
|
||||
{
|
||||
this->shatter ();
|
||||
}
|
||||
|
||||
void shatter ()
|
||||
{
|
||||
this->clear (true);
|
||||
}
|
||||
|
@ -27,8 +27,6 @@
|
||||
#ifndef _QSE_CMN_MMGR_HPP_
|
||||
#define _QSE_CMN_MMGR_HPP_
|
||||
|
||||
#include <qse/types.h>
|
||||
#include <qse/macros.h>
|
||||
#include <qse/Exception.hpp>
|
||||
|
||||
/////////////////////////////////
|
||||
|
@ -77,7 +77,7 @@ protected:
|
||||
while (size > 0) this->buffer[--size] = c;
|
||||
}
|
||||
|
||||
void dispose (Mmgr* mmgr)
|
||||
void shatter (Mmgr* mmgr)
|
||||
{
|
||||
QSE_ASSERT (this->buffer != QSE_NULL);
|
||||
::operator delete (this->buffer, mmgr);
|
||||
@ -283,8 +283,21 @@ protected:
|
||||
{
|
||||
if (sd->deref () <= 0)
|
||||
{
|
||||
sd->dispose (this->getMmgr());
|
||||
// i can't pass an argument to the destructor.
|
||||
// destroy the actual contents via the shatter() funtion
|
||||
// call the destructor for completeness only
|
||||
sd->shatter (this->getMmgr());
|
||||
#if defined(__BORLANDC__)
|
||||
// BCC55 doesn't support calling the destructor explicitly.
|
||||
// anyway, it's safe not to call it for the way i destroy
|
||||
// the object using the shatter() call above
|
||||
//
|
||||
// DO NOTHING
|
||||
//
|
||||
#else
|
||||
// call the destructor
|
||||
sd->~StringItem ();
|
||||
#endif
|
||||
::operator delete (sd, this->getMmgr());
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user