diff --git a/src/lib/scoped-holder-transfer.hpp b/src/lib/scoped-holder-transfer.hpp deleted file mode 100644 index 0f6a130a6..000000000 --- a/src/lib/scoped-holder-transfer.hpp +++ /dev/null @@ -1,136 +0,0 @@ -/* - SCOPED-HOLDER-TRANSFER.hpp - using ScopedHolder within a STL vector - - Copyright (C) - 2008, Hermann Vosseler - -  **Lumiera** is free software; you can redistribute it and/or modify it -  under the terms of the GNU General Public License as published by the -  Free Software Foundation; either version 2 of the License, or (at your -  option) any later version. See the file COPYING for further details. - -*/ - - -/** @file scoped-holder-transfer.hpp - ** A mechanism to take ownership without allowing copy. - ** @deprecated obsolete concept, superseded by C++11 rvalue references - ** @todo expunge this! - */ - - - -#ifndef LIB_SCOPEDHOLDER_TRANSFER_H -#define LIB_SCOPEDHOLDER_TRANSFER_H - -#include "lib/error.hpp" -#include - - -namespace lib { - - - - - /** - * Addendum to scoped-holder.hpp for transferring the lifecycle - * management to another instance. Using these wrappers within - * STL vector and similar containers may result in the need to - * do a re-allocation in response to a request to grow. - * Obviously such a feature needs support by the objects being - * wrapped, which should provide an operation for transferring - * lifecycle management in a controlled fashion. This behaviour - * is similar to std::auto_ptr, but because we use a separate - * dedicated operation, we avoid some of the dangers pertaining - * the use of the latter: just taking the "value" can't kill - * the managed object. - * \par - * To implement this feature we need - * - a custom allocator to be used by the vector. By default - * it is built as a thin proxy round std::allocator. - * - the \em noncopyable type to be managed within the vector - * needs to provide a custom extension point: when the - * allocator detects the need to transfer control between - * two instances, it will invoke a free function named - * transfer_control(TY& from, TY& to) intended - * to be found by ADL. Note: in case this function throws, - * it **must not have any side effects**. - * - besides, the _noncopyable_ type needs to provide an - * operator bool() yielding true iff currently - * containing an managed object. This is similar to - * std::unique_ptr or even the behaviour of a plain - * old raw pointer, which is equivalent to `true` - * when the pointer isn'T `NULL` - * @deprecated obsoleted by C++11 rvalue references - * - */ - template> - class Allocator_TransferNoncopyable - { - typedef Allocator_TransferNoncopyable _ThisType; - - PAR par_; - - - public: - typedef typename PAR::size_type size_type; - typedef typename PAR::difference_type difference_type; - typedef typename PAR::pointer pointer; - typedef typename PAR::const_pointer const_pointer; - typedef typename PAR::reference reference; - typedef typename PAR::const_reference const_reference; - typedef typename PAR::value_type value_type; - - template - struct rebind - { typedef Allocator_TransferNoncopyable other; }; - - Allocator_TransferNoncopyable() { } - - Allocator_TransferNoncopyable(const _ThisType& allo) - : par_(allo.par_) { } - Allocator_TransferNoncopyable(const PAR& allo) - : par_(allo) { } - - template - Allocator_TransferNoncopyable(const std::allocator&) { } - - ~Allocator_TransferNoncopyable() { } - - - //------------proxying-the-parent-allocator------------------------------------ - - size_type max_size() const { return par_.max_size(); } - pointer address(reference r) const { return par_.address(r); } - const_pointer address(const_reference cr) const { return par_.address(cr); } - pointer allocate(size_type n, const void *p=0){ return par_.allocate(n,p); } - void deallocate(pointer p, size_type n) { par_.deallocate(p,n); } - void destroy(pointer p) { par_.destroy(p); } - - - void - construct (pointer p, const TY& ref) - { - new(p) TY(); /////////////////////TICKET #1204 - ASSERT (p); - ASSERT (!(*p), "protocol violation: target already manages another object."); - if (ref) - transfer_control (const_cast(ref), *p); - } - }; - - template - inline bool - operator== (Allocator_TransferNoncopyable const&, Allocator_TransferNoncopyable const&) - { return true; } - - template - inline bool - operator!= (Allocator_TransferNoncopyable const&, Allocator_TransferNoncopyable const&) - { return false; } - - - - -} // namespace lib -#endif diff --git a/src/lib/scoped-holder.hpp b/src/lib/scoped-holder.hpp deleted file mode 100644 index 6a547c4c8..000000000 --- a/src/lib/scoped-holder.hpp +++ /dev/null @@ -1,248 +0,0 @@ -/* - SCOPED-HOLDER.hpp - general purpose wrapper for dealing with ownership problems - - Copyright (C) - 2008, Hermann Vosseler - -  **Lumiera** is free software; you can redistribute it and/or modify it -  under the terms of the GNU General Public License as published by the -  Free Software Foundation; either version 2 of the License, or (at your -  option) any later version. See the file COPYING for further details. - -*/ - -/** @file scoped-holder.hpp - ** Some wrappers for coping with ownership problems. - ** Working with collections of objects, especially in conjunction with - ** polymorphism, can be challenging when we are bound to care for lifecycle - ** and ownership for the contained classes. There are several solutions, - ** including the boost::ptr_container library or lib::ScopedPtrVect, the - ** use of shared_ptr or even a garbage collector. Sometimes circumstances - ** rather call for a very simple or lightweight solution though. - ** - ** ScopedPtrHolder is a simple extension to std::unique_ptr, enabling - ** to use it within STL containers if we stick to a specific protocol. - ** The idea is to permit copying as long as the unique_ptr is empty. - ** This can be used to allow for extension of the STL container on - ** demand, i.e. to handle the typical situation of a registry which - ** is initialised lazily, but only released in a controlled fashion. - ** - ** ScopedHolder implements a similar concept for in-place storage of - ** noncopyable objects within STL containers. - ** - ** While the added copy operations (secured with the "empty" requirement) - ** are enough to use those holders within fixed sized STL containers, - ** supporting dynamic growth (like in std::vector#resize() ) additionally - ** requires a facility to transfer the lifecycle management control between - ** holder instances. This is the purpose of the \c transfer_control - ** friend function. - ** - ** @deprecated this is a pre C++11 concept and superseded by rvalue references /////////////////////////////TICKET #958 - ** - ** @see scoped-holder-test.cpp - ** @see scoped-holder-transfer.hpp use in std::vector - ** @see scoped-ptrvect.hpp simple pointer-holding collection - */ - - -#ifndef LIB_SCOPED_HOLDER_H -#define LIB_SCOPED_HOLDER_H - -#include "lib/error.hpp" - -#include - - -namespace lib { - - - - - /** - * Extension to std::unique_ptr, allowing copy operations - * on empty pointers (i.e. contained pointer is null). - * @throw error::Logic on attempt to copy otherwise - */ - template - class ScopedPtrHolder - : public std::unique_ptr - { - typedef std::unique_ptr _Parent; - - static B* must_be_null (_Parent const& ptr) - { - if (ptr) - throw lumiera::error::Logic("ScopedPtrHolder protocol violation: " - "attempt to copy from non-null."); - return 0; - } - - public: - ScopedPtrHolder() - : _Parent{} - { } - - template - explicit ScopedPtrHolder (SU * p) // never throws - : _Parent(p) - { } - - template - explicit ScopedPtrHolder (std::unique_ptr pu) // never throws - : _Parent(pu.release()) - { } - - ScopedPtrHolder (ScopedPtrHolder const& ref) - : _Parent(must_be_null (ref)) - { } - - ScopedPtrHolder& - operator= (ScopedPtrHolder const& ref) - { - must_be_null (*this); - must_be_null (ref); - return *this; - } - - friend void - transfer_control (ScopedPtrHolder& from, ScopedPtrHolder& to) - { - if (!from) return; - TRACE (test, "transfer_control... from=%p to=%p",&from, &to); - must_be_null (to); - to.swap(from); - } - }; - - - - - /** - * Inline buffer holding and owning an object similar to unique_ptr. - * Access to the contained object is similar to a smart-pointer, - * but the object isn't heap allocated, rather placed into an - * buffer within ScopedHolder. Initially, ScopedHolder is empty - * and behaves like a null pointer. The contained object must be - * created explicitly by calling #create() (using the default ctor). - * This state change is remembered (requiring 1 char of additional - * storage). After the creation of the object, ScopedHolder is - * effectively noncopyable, which is enforced by run-time checks. - * ScopedHolder may be used to hold noncopyable objects within STL - * containers inline without extra heap allocation. - */ - template - class ScopedHolder - { - char content_[sizeof(TY)]; - char created_; - - - static char - must_be_empty (ScopedHolder const& ref) - { - if (ref) - throw lumiera::error::Logic("ScopedHolder protocol violation: " - "copy operation after having invoked create()."); - return 0; - } - - public: - ScopedHolder() - : created_(0) - { } - - ~ScopedHolder() { clear(); } - - - TY& - create () - { - ASSERT (!created_); - TY * obj = new(content_) TY(); - ++created_; - return *obj; - } - - TY& - create (TY const& o) ///< place new content object using copy ctor - { - ASSERT (!created_); - TY * obj = new(content_) TY(o); - ++created_; - return *obj; - } - - void - clear () - { - if (created_) - get()->~TY(); - created_ = false; - } - - - ScopedHolder (ScopedHolder const& ref) - : created_(must_be_empty (ref)) - { } - - ScopedHolder& - operator= (ScopedHolder const& ref) - { - must_be_empty (*this); - must_be_empty (ref); - return *this; - } - - - TY& - operator* () const - { - ASSERT (created_); - return (TY&) content_; //////////////////////////////////////////////////////////////////TICKET #958 : GCC-14 warns here -- really time to get rid of this class alltogether - } - - TY* - operator-> () const - { - ASSERT (created_); - return (TY*) &content_; - } - - TY* get() const // never throws - { - return (TY*) &content_; - } - - - - explicit operator bool() const { return created_; } - bool operator! () const { return not created_; } - - - friend void - transfer_control (ScopedHolder& from, ScopedHolder& to) - { - if (!from) return; - TRACE (test, "transfer_control... from=%p to=%p",&from, &to); - must_be_empty (to); - to.create(); - try - { - transfer_control(*from,*to); // note: assumed to have no side-effect in case it throws - from.clear(); - return; - } - catch(...) - { - to.clear(); - WARN (test, "transfer_control operation aborted."); - throw; - } - } - }; - - - - -} // namespace lib -#endif diff --git a/src/steam/engine/tracking-heap-block-provider.cpp b/src/steam/engine/tracking-heap-block-provider.cpp index 3c2a2cbc7..996f082e5 100644 --- a/src/steam/engine/tracking-heap-block-provider.cpp +++ b/src/steam/engine/tracking-heap-block-provider.cpp @@ -20,7 +20,6 @@ #include "lib/error.hpp" #include "include/logging.h" #include "lib/scoped-ptrvect.hpp" -#include "lib/scoped-holder.hpp" #include "lib/util-foreach.hpp" #include "steam/engine/tracking-heap-block-provider.hpp" @@ -30,7 +29,6 @@ using util::and_all; using std::vector; -using lib::ScopedHolder; using lib::ScopedPtrVect; @@ -87,8 +85,7 @@ namespace engine { namespace diagn { - typedef ScopedPtrVect PoolVec; - typedef ScopedHolder PoolHolder; + using PoolBlocks = ScopedPtrVect; /** * @internal Pool of allocated buffer Blocks of a specific size. @@ -105,19 +102,18 @@ namespace engine { { uint maxAllocCount_; size_t memBlockSize_; - PoolHolder blockList_; + PoolBlocks blockList_; public: BlockPool() : maxAllocCount_(0) // unlimited by default , memBlockSize_(0) - , blockList_() + , blockList_{} { } void initialise (size_t blockSize) { - blockList_.create(); memBlockSize_ = blockSize; } // standard copy operations are valid, but will @@ -134,19 +130,18 @@ namespace engine { void discard() { - if (blockList_) - for (Block& block : *blockList_) - block.markReleased(); + for (Block& block : blockList_) + block.markReleased(); } uint prepare_for (uint number_of_expected_buffers) { if (maxAllocCount_ && - maxAllocCount_ < blockList_->size() + number_of_expected_buffers) + maxAllocCount_ < blockList_.size() + number_of_expected_buffers) { - ASSERT (maxAllocCount_ >= blockList_->size()); - return maxAllocCount_ - blockList_->size(); + ASSERT (maxAllocCount_ >= blockList_.size()); + return maxAllocCount_ - blockList_.size(); } // currently no hard limit imposed return number_of_expected_buffers; @@ -156,34 +151,34 @@ namespace engine { Block& createBlock() { - return blockList_->manage (new Block(memBlockSize_)); + return blockList_.manage (new Block(memBlockSize_)); } Block* find (void* blockLocation) { - return pick_Block_by_storage (*blockList_, blockLocation); + return pick_Block_by_storage (blockList_, blockLocation); } Block* transferResponsibility (Block* allocatedBlock) { - return blockList_->detach (allocatedBlock); + return blockList_.detach (allocatedBlock); } size_t size() const { - return blockList_->size(); + return blockList_.size(); } bool isValid() const { - return bool(blockList_); + return not blockList_.empty(); } explicit @@ -197,8 +192,7 @@ namespace engine { verify_all_children_idle() { try { - if (blockList_) - return and_all (*blockList_, is_in_sane_state); + return and_all (blockList_, is_in_sane_state); } ERROR_LOG_AND_IGNORE (test, "State verification of diagnostic BufferProvider allocation pool"); return true; diff --git a/tests/15library.tests b/tests/15library.tests index cf0416473..3816752ea 100644 --- a/tests/15library.tests +++ b/tests/15library.tests @@ -577,32 +577,6 @@ return: 0 END -TEST "ScopedHolder_test" ScopedHolder_test <... -out: checking ScopedPtrHolder... -return: 0 -END - - -TEST "ScopedHolderTransfer_test" ScopedHolderTransfer_test <... -out-lit: . -out-lit: ..install one element at index[0] -out-lit: . -out-lit: ..*** resize table to 16 elements -out-lit: . -out-lit: .throw some exceptions... -out-lit: checking ScopedPtrHolder... -out-lit: . -out-lit: ..install one element at index[0] -out-lit: . -out-lit: ..*** resize table to 16 elements -out-lit: . -out-lit: .throw some exceptions... -return: 0 -END - - TEST "Managed Collection (I)" ScopedCollection_test < 'Meh?' return: 0 END - -TEST "VectorTransfer_test" VectorTransfer_test < received_; + ItemWrapper received_; public: TestListener() - { - received_.create (Time::ZERO); - } + : received_{TI{Time::ZERO}} + { } TestListener(TI const& initialValue) - { - received_.create (initialValue); - } + : received_{initialValue} + { } void operator() (TI const& changeValue) const { - received_.clear(); - received_.create (changeValue); + received_ = changeValue; } TI const& diff --git a/tests/library/scoped-holder-test.cpp b/tests/library/scoped-holder-test.cpp deleted file mode 100644 index 12e400128..000000000 --- a/tests/library/scoped-holder-test.cpp +++ /dev/null @@ -1,244 +0,0 @@ -/* - ScopedHolder(Test) - holding and owning noncopyable objects - - Copyright (C) - 2008, Hermann Vosseler - -  **Lumiera** is free software; you can redistribute it and/or modify it -  under the terms of the GNU General Public License as published by the -  Free Software Foundation; either version 2 of the License, or (at your -  option) any later version. See the file COPYING for further details. - -* *****************************************************************/ - -/** @file scoped-holder-test.cpp - ** unit test \ref ScopedHolder_test - */ - - - -#include "lib/test/run.hpp" -#include "lib/test/test-helper.hpp" -#include "lib/format-cout.hpp" -#include "lib/util.hpp" -#include "lib/error.hpp" - -#include "lib/scoped-holder.hpp" -#include "lib/test/tracking-dummy.hpp" - -#include - - -namespace lib { -namespace test{ - - using ::Test; - using util::isnil; - using lumiera::error::LUMIERA_ERROR_LOGIC; - - using std::map; - - typedef ScopedHolder HolderD; - typedef ScopedPtrHolder PtrHolderD; - - - /******************************************************************************//** - * @test ScopedHolder and ScopedPtrHolder are initially empty and copyable. - * After taking ownership, they prohibit copy operations, manage the - * lifecycle of the contained object and provide smart-ptr like access. - * A series of identical tests is conducted both with the ScopedPtrHolder - * (the contained objects are heap allocated but managed by the holder) - * and with the ScopedHolder (objects placed inline) - */ - class ScopedHolder_test : public Test - { - - virtual void - run (Arg) - { - - cout << "checking ScopedHolder...\n"; - checkAllocation(); - checkErrorHandling(); - checkCopyProtocol(); - checkSTLContainer(); - - cout << "checking ScopedPtrHolder...\n"; - checkAllocation(); - checkErrorHandling(); - checkCopyProtocol(); - checkSTLContainer(); - } - - void create_contained_object (HolderD& holder) { holder.create(); } - void create_contained_object (PtrHolderD& holder) { holder.reset(new Dummy()); } - - - template - void - checkAllocation() - { - CHECK (0 == Dummy::checksum()); - { - HO holder; - CHECK (!holder); - CHECK (0 == Dummy::checksum()); - - create_contained_object (holder); - CHECK (holder); - CHECK (false != bool(holder)); - CHECK (bool(holder) != false); - - CHECK (0 < Dummy::checksum()); - CHECK ( &(*holder)); - CHECK (holder->calc(2) == 2 + Dummy::checksum()); - - Dummy *rawP = holder.get(); - CHECK (rawP); - CHECK (holder); - CHECK (rawP == &(*holder)); - CHECK (rawP->calc(-5) == holder->calc(-5)); - - TRACE (test, "holder at %p", &holder); - TRACE (test, "object at %p", holder.get() ); - TRACE (test, "size(object) = %zu", sizeof(*holder)); - TRACE (test, "size(holder) = %zu", sizeof(holder)); - } - CHECK (0 == Dummy::checksum()); - } - - - template - void - checkErrorHandling() - { - CHECK (0 == Dummy::checksum()); - { - HO holder; - - Dummy::activateCtorFailure(); - try - { - create_contained_object (holder); - NOTREACHED ("expect failure in ctor"); - } - catch (int val) - { - CHECK (0 != Dummy::checksum()); - Dummy::checksum() -= val; - CHECK (0 == Dummy::checksum()); - } - CHECK (!holder); /* because the exception happens in ctor - object doesn't count as "created" */ - Dummy::activateCtorFailure(false); - } - CHECK (0 == Dummy::checksum()); - } - - - template - void - checkCopyProtocol() - { - CHECK (0 == Dummy::checksum()); - { - HO holder; - HO holder2 (holder); - holder2 = holder; - // copy and assignment of empty holders is tolerated - - // but after enclosing an object it will be copy protected... - CHECK (!holder); - create_contained_object (holder); - CHECK (holder); - long currSum = Dummy::checksum(); - void* adr = holder.get(); - - VERIFY_ERROR(LOGIC, holder2 = holder ); - CHECK (holder); - CHECK (!holder2); - CHECK (holder.get()==adr); - CHECK (Dummy::checksum()==currSum); - - VERIFY_ERROR(LOGIC, holder = holder2 ); - CHECK (holder); - CHECK (!holder2); - CHECK (holder.get()==adr); - CHECK (Dummy::checksum()==currSum); - - create_contained_object (holder2); - CHECK (holder2); - CHECK (Dummy::checksum() != currSum); - currSum = Dummy::checksum(); - - VERIFY_ERROR(LOGIC, holder = holder2 ); - CHECK (holder); - CHECK (holder2); - CHECK (holder.get()==adr); - CHECK (Dummy::checksum()==currSum); - - VERIFY_ERROR(LOGIC, HO holder3 (holder2) ); - CHECK (holder); - CHECK (holder2); - CHECK (Dummy::checksum()==currSum); - } - CHECK (0 == Dummy::checksum()); - } - - - /** @test collection of noncopyable objects - * maintained within a STL map - */ - template - void - checkSTLContainer() - { - typedef std::map MapHO; - - CHECK (0 == Dummy::checksum()); - { - MapHO maph; - CHECK (isnil (maph)); - - for (uint i=0; i<100; ++i) - { - HO & contained = maph[i]; - CHECK (!contained); - } // 100 holder objects created by sideeffect - // ..... without creating any contained object! - CHECK (0 == Dummy::checksum()); - CHECK (!isnil (maph)); - CHECK (100==maph.size()); - - for (uint i=0; i<100; ++i) - { - create_contained_object (maph[i]); - CHECK (maph[i]); - CHECK (0 < maph[i]->calc(12)); - } - CHECK (100==maph.size()); - CHECK (0 != Dummy::checksum()); - - - long value55 = maph[55]->calc(0); - long currSum = Dummy::checksum(); - - CHECK (1 == maph.erase(55)); - CHECK (Dummy::checksum() == currSum - value55); // proves object#55's dtor has been invoked - CHECK (maph.size() == 99); - - maph[55]; // create new empty holder by sideeffect... - CHECK (&maph[55]); - CHECK (!maph[55]); - CHECK (maph.size() == 100); - } - CHECK (0 == Dummy::checksum()); - } - - - }; - - LAUNCHER (ScopedHolder_test, "unit common"); - - -}} // namespace lib::test diff --git a/tests/library/scoped-holder-transfer-test.cpp b/tests/library/scoped-holder-transfer-test.cpp deleted file mode 100644 index b2c3b11c9..000000000 --- a/tests/library/scoped-holder-transfer-test.cpp +++ /dev/null @@ -1,232 +0,0 @@ -/* - ScopedHolderTransfer(Test) - managing noncopyable objects within a growing vector - - Copyright (C) - 2008, Hermann Vosseler - -  **Lumiera** is free software; you can redistribute it and/or modify it -  under the terms of the GNU General Public License as published by the -  Free Software Foundation; either version 2 of the License, or (at your -  option) any later version. See the file COPYING for further details. - -* *****************************************************************/ - -/** @file scoped-holder-transfer-test.cpp - ** unit test \ref ScopedHolderTransfer_test - */ - - - -#include "lib/test/run.hpp" -#include "lib/util.hpp" - -#include "lib/scoped-holder.hpp" -#include "lib/scoped-holder-transfer.hpp" -#include "lib/test/tracking-dummy.hpp" - -#include -#include - - -namespace lib { -namespace test { - - using ::Test; - using util::isnil; - - using std::vector; - using std::cout; - - namespace { // extending the Dummy for our special purpose.... - - bool throw_in_transfer = false; - - class FixedDummy - : public Dummy - { - public: - FixedDummy() - { - TRACE (test, "CTOR FixedDummy() --> this=%p val=%d", this, getVal()); - } - - ~FixedDummy() - { - TRACE (test, "DTOR ~FixedDummy() this=%p val=%d", this, getVal()); - } - - friend void - transfer_control (FixedDummy& from, FixedDummy& to) - { - TRACE (test, "TRANSFER target=%p <-- source=%p (%d,%d)", &to,&from, to.getVal(),from.getVal()); - - if (throw_in_transfer) - throw to.getVal(); - - swap (from,to); - from.setVal(0); // remove the old Dummy from accounting (checksum) - } - - }; - - - typedef ScopedHolder HolderD; - typedef ScopedPtrHolder PtrHolderD; - - template - struct Table - { - typedef Allocator_TransferNoncopyable Allo; - typedef typename std::vector Type; - - }; - - }//(End) test helpers - - - - - - /******************************************************************************//** - * @test growing a vector containing noncopyable objects wrapped into ScopedHolder - * instances. This requires the use of a custom allocator, invoking a - * \c transfer_control() function to be provided for the concrete - * noncopyable class type, being invoked when the vector - * needs to reallocate. - */ - class ScopedHolderTransfer_test : public Test - { - - virtual void - run (Arg) - { - - cout << "checking ScopedHolder...\n"; - buildVector(); - growVector(); - checkErrorHandling(); - - cout << "checking ScopedPtrHolder...\n"; - buildVector(); - growVector(); - checkErrorHandling(); - } - - void create_contained_object (HolderD& holder) { holder.create(); } - void create_contained_object (PtrHolderD& holder) { holder.reset(new FixedDummy()); } - - - template - void - buildVector() - { - CHECK (0 == Dummy::checksum()); - { - typedef typename Table::Type Vect; - - Vect table(50); - CHECK (0 == Dummy::checksum()); - - for (uint i=0; i<10; ++i) - create_contained_object (table[i]); - - CHECK (0 < Dummy::checksum()); - CHECK ( table[9]); - CHECK (!table[10]); - - Dummy *rawP = table[5].get(); - CHECK (rawP); - CHECK (table[5]); - CHECK (rawP == &(*table[5])); - CHECK (rawP->calc(-555) == table[5]->calc(-555)); - } - CHECK (0 == Dummy::checksum()); - } - - - template - void - growVector() - { - CHECK (0 == Dummy::checksum()); - { - typedef typename Table::Type Vect; - - Vect table; - table.reserve(2); - CHECK (0 == Dummy::checksum()); - - cout << ".\n..install one element at index[0]\n"; - table.push_back(HO()); - CHECK (0 == Dummy::checksum()); - - create_contained_object (table[0]); // switches into "managed" state - CHECK (0 < Dummy::checksum()); - int theSum = Dummy::checksum(); - - cout << ".\n..*** resize table to 16 elements\n"; - for (uint i=0; i<15; ++i) - table.push_back(HO()); - - CHECK (theSum == Dummy::checksum()); - } - CHECK (0 == Dummy::checksum()); - } - - - template - void - checkErrorHandling() - { - CHECK (0 == Dummy::checksum()); - { - typedef typename Table::Type Vect; - - Vect table(5); - table.reserve(5); - CHECK (0 == Dummy::checksum()); - - create_contained_object (table[2]); - create_contained_object (table[4]); - CHECK (0 < Dummy::checksum()); - int theSum = Dummy::checksum(); - - cout << ".\n.throw some exceptions...\n"; - Dummy::activateCtorFailure(); - try - { - create_contained_object (table[3]); - NOTREACHED ("ctor should throw"); - } - catch (int val) - { - CHECK (theSum < Dummy::checksum()); - Dummy::checksum() -= val; - CHECK (theSum == Dummy::checksum()); - } - CHECK ( table[2]); - CHECK (!table[3]); // not created because of exception - CHECK ( table[4]); - - Dummy::activateCtorFailure(false); - throw_in_transfer=true; // can do this only when using ScopedHolder - try - { - table.resize(10); - } - catch (int val) - { - CHECK ( table.size() < 10); - } - CHECK (theSum == Dummy::checksum()); - throw_in_transfer=false; - } - CHECK (0 == Dummy::checksum()); - } - - }; - - LAUNCHER (ScopedHolderTransfer_test, "unit common"); - - -}} // namespace lib::test diff --git a/tests/library/vector-transfer-test.cpp b/tests/library/vector-transfer-test.cpp deleted file mode 100644 index b55423868..000000000 --- a/tests/library/vector-transfer-test.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/* - VectorTransfer(Test) - intercept object copying when a STL vector grows - - Copyright (C) - 2008, Hermann Vosseler - -  **Lumiera** is free software; you can redistribute it and/or modify it -  under the terms of the GNU General Public License as published by the -  Free Software Foundation; either version 2 of the License, or (at your -  option) any later version. See the file COPYING for further details. - -* *****************************************************************/ - -/** @file vector-transfer-test.cpp - ** unit test \ref VectorTransfer_test - */ - - - -#include "lib/test/run.hpp" - -#include "lib/scoped-holder-transfer.hpp" -#include "lib/test/tracking-dummy.hpp" -#include "lib/format-cout.hpp" - -#include - - -namespace lib { -namespace test { - - using ::Test; - using std::vector; - - namespace { // extending the Dummy for our special purpose.... - - class TransDummy - : public Dummy - { - public: - TransDummy() - { - TRACE (test, "CTOR TransDummy() --> this=%p", this); - setVal(0); // we use val_==0 to mark the "empty" state - } - - ~TransDummy() - { - TRACE (test, "DTOR ~TransDummy() this=%p", this); - } - - /* to make Dummy usable within vector, we need to provide - * \em special copy operations, an operator bool() and - * a transfer_control friend function to be used by - * our special allocator. - */ - - TransDummy (const TransDummy& o) - : Dummy() - { - TRACE (test, "COPY-ctor TransDummy( ref=%p ) --> this=%p", &o,this); - CHECK (!o, "protocol violation: real copy operations inhibited"); - } - - TransDummy& - operator= (TransDummy const& ref) - { - TRACE (test, "COPY target=%p <-- source=%p", this,&ref); - CHECK (!(*this)); - CHECK (!ref, "protocol violation: real copy operations inhibited"); - return *this; - } - - void - setup (int x=0) - { - setVal (x? x : rani (10000)); - TRACE (test, "CREATE val=%d ---> this=%p", getVal(),this); - } - - - // define implicit conversion to "bool" the naive way... - operator bool() const - { - return 0!=getVal(); - } - - - friend void transfer_control (TransDummy& from, TransDummy& to); - - }; - - - - void - transfer_control (TransDummy& from, TransDummy& to) - { - TRACE (test, "TRANSFER target=%p <-- source=%p", &to,&from); - CHECK (!to, "protocol violation: target already manages another object"); - to.setVal (from.getVal()); - from.setVal(0); - } - - typedef Allocator_TransferNoncopyable Allo; - typedef vector TransDummyVector; - } - - - - - /******************************************************************************//** - * @test growing (re-allocating) a vector with noncopyable objects, with the - * help of a special Allocator and a custom \c transfer_control operation - * provided by the contained objects. The idea is to allow some special - * copy-operations for the purpose of re-allocations within the vector, - * without requiring the object to be really copyable. - */ - class VectorTransfer_test : public Test - { - - virtual void - run (Arg) - { - seedRand(); - - cout << "\n..setup table space for 2 elements\n"; - TransDummyVector table; - table.reserve(2); - CHECK (0 == Dummy::checksum()); - - cout << "\n..install one element at index[0]\n"; - table.push_back(TransDummy()); - CHECK (0 == Dummy::checksum()); - - table[0].setup(); // switches into "managed" state - CHECK (0 < Dummy::checksum()); - int theSum = Dummy::checksum(); - - cout << "\n..*** resize table to 5 elements\n"; - table.resize(5); - CHECK (theSum==Dummy::checksum()); - - cout << "\n..install another element\n"; - table[3].setup(375); - CHECK (theSum+375==Dummy::checksum()); - - cout << "\n..kill all elements....\n"; - table.clear(); - CHECK (0 == Dummy::checksum()); - } - - }; - - LAUNCHER (VectorTransfer_test, "unit common"); - - -}} // namespace lib::test diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 7efa2c6d8..e1c0fab9f 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -163473,9 +163473,7 @@ Since then others have made contributions, see the log for the history. - - - +

»Commands« sind selber im Schwebezustand @@ -163483,16 +163481,13 @@ Since then others have made contributions, see the log for the history. - - - +

Zwar halte ich Commands nicht für insgesamt obsolet — wir werden so etwas definitiv brauchen, da unser GUI per Messaging angebunden ist. Aber es ist bisher unklar geblieben, wie die Schnittstelle zur Sessinon tatsächlich aussehen wird, auf der die Command-Funktoren dann einmal arbeiten sollen. Zudem waren die Commands auch als Teil eines »Command-Systems« gedacht, welches auch UNDO und REDO ermöglicht. Und in dieser Hinsicht bewege ich mich schon seit längerer Zeit in Richtung auf Events und Event-sourcing. Damit wäre ein Großteil der Komplexität im bestehenden Command-Framework hinfällig

- -
+
@@ -163502,16 +163497,13 @@ Since then others have made contributions, see the log for the history. - - - +

pfui ... einen Konstruktor-Fehler unterdrücken und stattdessen ein default-konstruiertes Objekt unterschieben, und das auch noch in einer Funktion, die emplace() heißt...

- -
+ @@ -163545,16 +163537,13 @@ Since then others have made contributions, see the log for the history. - - - +

ReplacableIterm ist schlampig definiert

- -
+ @@ -163563,16 +163552,13 @@ Since then others have made contributions, see the log for the history. - - - +

...denn er würde ReplacableItem in ein ReplacableItem einpflanzen — also ein Stockwerk zu viel

- -
+
@@ -163583,16 +163569,13 @@ Since then others have made contributions, see the log for the history. - - - +

wollte Time, Duration etc. in einem Command als Memento binden

- -
+
@@ -163634,9 +163617,7 @@ Since then others have made contributions, see the log for the history. - - - +

...hat bereits keinerlei Verwendungen mehr (hab es wohl schrittweise durch std::ref() ersetzt ... ohne eigens darauf zu achten) @@ -163658,21 +163639,18 @@ Since then others have made contributions, see the log for the history. - + - - - +

...was man auch daran sieht, daß es das gleiche Konezpt in Boost gibt; wäre da nicht Boost-serialisation, dann könnte man das als Ersatz nehmen

- -
+
@@ -163689,27 +163667,21 @@ Since then others have made contributions, see the log for the history. - - - +

außerdem habe ich hier bereits pervasiv mit einem Typ-Präfix _Vect::  dekoriert

- -
+ - - - +

...was darauf hindeutet, daß ich bereits Probleme mit der Eindeutigkeit von Namen hatte, bzw. die Notation ohnehin verwirrend war.

- -
+
@@ -163721,26 +163693,25 @@ Since then others have made contributions, see the log for the history.
- + + - - - +

allein schon wenn man so viel Kommentar zur Rechtfertigung schreiben muß; und dann ist das Ganze auch noch stateful, und es führte zu einer Erweiterun, ScopedHolderTransfer, mit noch viel mehr Kommentar und Erläuterung und umständlichen Tests (und dann wird das am Ende doch fast nicht verwendet)

- -
+
- + + - + @@ -163751,38 +163722,36 @@ Since then others have made contributions, see the log for the history. - + - - - +

hatte das zwar geschaffen, um non-copyable Objekte in einen Vector packen zu können — aber es ist kein Container, sondern lediglich ein inline-Buffer

- -
+ +
- + + + - + + - - - +

für einen Test / Diagnose-Container ist das in der Tat sinnvoll, denn man möchte da nicht die Komplexität mit der Verwaltung von Extents  haben (größere Speicherblöcke, aus denen dann kleinere Allokationen ausgegeben werden)

- -
+
@@ -163790,23 +163759,18 @@ Since then others have made contributions, see the log for the history. - - - +

dann könnte man ihn nämlich ohne weiteres direkt in jedem STL-Container per emplace einbringen, selbst in std::vector

- -
+
- + - - - +

unique_ptr kann das ja auc @@ -163820,16 +163784,27 @@ Since then others have made contributions, see the log for the history. + + - + + + + + + - + + + + +