Alien-SmokeQt

 view release on metacpan or  search on metacpan

generator/parser/rpp/appendedlist.h  view on Meta::CPAN

/*
   Copyright 2008 David Nolden <david.nolden.kdevelop@art-master.de>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License version 2 as published by the Free Software Foundation.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.
*/

#ifndef APPENDEDLIST_H
#define APPENDEDLIST_H

#include <QtCore/QMutex>
#include <QtCore/QVector>
#include <QtCore/QStack>
#include <QtCore/QPair>
// #include <kglobal.h>
// #include <kdebug.h>
#include "../kdevvarlengtharray.h"
#include <iostream>
#include <time.h>

namespace KDevelop {
class AbstractItemRepository;
/**
 * This file contains macros and classes that can be used to conveniently implement classes that store the data of an arbitrary count
 * of additional lists within the same memory block directly behind the class data, in a way that one the whole data can be stored by one copy-operation
 * to another place, like needed in ItemRepository. These macros simplify having two versions of a class: One that has its lists attached in memory,
 * and one version that has them contained as a directly accessible KDevVarLengthArray. Both versions have their lists accessible through access-functions,
 * have a completeSize() function that computes the size of the one-block version, and a copyListsFrom(..) function which can copy the lists from one
 * version to the other.
 *
 * @warning Always follow these rules:
 * You must call initalizeAppendedLists(bool) on construction, also in any copy-constructor, but before calling copyFrom(..).
 * The parameter to that function should be whether the lists in the items should be dynamic, and thus most times "true".
 * You must call freeAppendedLists() on destruction, our you will be leaking memory(only when dynamic)
 *
 * For each embedded list, you must use macros to define a global hash that will be used to allocate the temporary lists, example fir identifier.cpp:
 * DEFINE_LIST_MEMBER_HASH(IdentifierPrivate, templateIdentifiers, uint);
 *
 * See identifier.cpp for an example how to use these classes. @todo Document this a bit more
 * */


enum {
  DynamicAppendedListMask = 1 << 31
};
enum {
  DynamicAppendedListRevertMask = 0xffffffff - DynamicAppendedListMask
};
/**
 * Manages a repository of items for temporary usage. The items will be allocated with an index on alloc(),
 * and freed on free(index). When freed, the same index will be re-used for a later allocation, thus no real allocations
 * will be happening in most cases.
 * The returned indices will always be ored with DynamicAppendedListMask.
 *
 */
template<class T, bool threadSafe = true>
class TemporaryDataManager {
  public:
    TemporaryDataManager(QString id = QString()) : m_itemsUsed(0), m_itemsSize(0), m_items(0), m_id(id) {
      uint first = alloc();  //Allocate the zero item, just to reserve that index
      Q_ASSERT(first == (uint)DynamicAppendedListMask);
    }
    ~TemporaryDataManager() {
      free(DynamicAppendedListMask); //Free the zero index, so we don't get wrong warnings
      uint cnt = usedItemCount();
      if(cnt) //Don't use kDebug, because that may not work during destruction
        std::cout << m_id.toLocal8Bit().data() << " There were items left on destruction: " << usedItemCount() << "\n";

      for(uint a = 0; a < m_itemsUsed; ++a)
        delete m_items[a];
    }

    inline T& getItem(uint index) {
      //For performance reasons this function does not lock the mutex, it's called too often and must be
      //extremely fast. There is special measures in alloc() to make this safe.
      Q_ASSERT(index & DynamicAppendedListMask);



( run in 1.011 second using v1.01-cache-2.11-cpan-acebb50784d )