More unique_ptr

This commit is contained in:
Thomas Goyne 2013-10-27 07:15:39 -07:00
parent eee4da0642
commit 95ef444c20
11 changed files with 81 additions and 107 deletions

View File

@ -88,7 +88,7 @@ UnknownElement::UnknownElement() : m_pImp(new Imp_T
UnknownElement::UnknownElement(const UnknownElement& unknown) : m_pImp(unknown.m_pImp->Clone()) {} UnknownElement::UnknownElement(const UnknownElement& unknown) : m_pImp(unknown.m_pImp->Clone()) {}
UnknownElement::UnknownElement(int number) : m_pImp(new Imp_T<Integer>(number)) {} UnknownElement::UnknownElement(int number) : m_pImp(new Imp_T<Integer>(number)) {}
UnknownElement::UnknownElement(const char *string) : m_pImp(new Imp_T<String>(string)) {} UnknownElement::UnknownElement(const char *string) : m_pImp(new Imp_T<String>(string)) {}
UnknownElement::~UnknownElement() { delete m_pImp; } UnknownElement::~UnknownElement() { }
#define DEFINE_UE_TYPE(Type) \ #define DEFINE_UE_TYPE(Type) \
UnknownElement::UnknownElement(Type const& val) : m_pImp(new Imp_T<Type>(val)) { } \ UnknownElement::UnknownElement(Type const& val) : m_pImp(new Imp_T<Type>(val)) { } \
@ -105,8 +105,7 @@ DEFINE_UE_TYPE(Null)
UnknownElement& UnknownElement::operator =(const UnknownElement& unknown) UnknownElement& UnknownElement::operator =(const UnknownElement& unknown)
{ {
delete m_pImp; m_pImp.reset(unknown.m_pImp->Clone());
m_pImp = unknown.m_pImp->Clone();
return *this; return *this;
} }

View File

@ -12,6 +12,7 @@ Author: Terry Caton
#include <deque> #include <deque>
#include <list> #include <list>
#include <map> #include <map>
#include <memory>
#include <string> #include <string>
#include <stdexcept> #include <stdexcept>
@ -126,7 +127,7 @@ private:
template <typename ElementTypeT> template <typename ElementTypeT>
ElementTypeT& CastTo(); ElementTypeT& CastTo();
Imp* m_pImp; std::unique_ptr<Imp> m_pImp;
}; };
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////

View File

@ -87,8 +87,9 @@ void AssFile::swap(AssFile &that) throw() {
} }
AssFile::AssFile(const AssFile &from) { AssFile::AssFile(const AssFile &from) {
Line.clone_from(from.Line, std::mem_fun_ref(&AssEntry::Clone), delete_ptr()); Line.clone_from(from.Line, std::mem_fun_ref(&AssEntry::Clone), [](AssEntry *e) { delete e; });
} }
AssFile& AssFile::operator=(AssFile from) { AssFile& AssFile::operator=(AssFile from) {
std::swap(*this, from); std::swap(*this, from);
return *this; return *this;

View File

@ -31,20 +31,20 @@
/// @brief Base classes for audio renderers (spectrum, waveform, ...) /// @brief Base classes for audio renderers (spectrum, waveform, ...)
/// @ingroup audio_ui /// @ingroup audio_ui
// Headers
#include "config.h" #include "config.h"
#include "audio_renderer.h" #include "audio_renderer.h"
#include "include/aegisub/audio_provider.h"
#include <libaegisub/util.h>
#include <algorithm> #include <algorithm>
#include <functional> #include <functional>
#include <wx/bitmap.h> #include <wx/bitmap.h>
#include <wx/dcmemory.h> #include <wx/dcmemory.h>
#include "include/aegisub/audio_provider.h"
using std::placeholders::_1; using std::placeholders::_1;
AudioRendererBitmapCacheBitmapFactory::AudioRendererBitmapCacheBitmapFactory(AudioRenderer *renderer) AudioRendererBitmapCacheBitmapFactory::AudioRendererBitmapCacheBitmapFactory(AudioRenderer *renderer)
@ -53,14 +53,9 @@ AudioRendererBitmapCacheBitmapFactory::AudioRendererBitmapCacheBitmapFactory(Aud
assert(renderer); assert(renderer);
} }
wxBitmap *AudioRendererBitmapCacheBitmapFactory::ProduceBlock(int /* i */) std::unique_ptr<wxBitmap> AudioRendererBitmapCacheBitmapFactory::ProduceBlock(int /* i */)
{ {
return new wxBitmap(renderer->cache_bitmap_width, renderer->pixel_height, 24); return agi::util::make_unique<wxBitmap>(renderer->cache_bitmap_width, renderer->pixel_height, 24);
}
void AudioRendererBitmapCacheBitmapFactory::DisposeBlock(wxBitmap *bmp)
{
delete bmp;
} }
size_t AudioRendererBitmapCacheBitmapFactory::GetBlockSize() const size_t AudioRendererBitmapCacheBitmapFactory::GetBlockSize() const
@ -79,7 +74,8 @@ AudioRenderer::AudioRenderer()
, renderer(0) , renderer(0)
, provider(0) , provider(0)
{ {
bitmaps.resize(AudioStyle_MAX, AudioRendererBitmapCache(256, AudioRendererBitmapCacheBitmapFactory(this))); for (int i = 0; i < AudioStyle_MAX; ++i)
bitmaps.emplace_back(256, AudioRendererBitmapCacheBitmapFactory(this));
// Make sure there's *some* values for those fields, and in the caches // Make sure there's *some* values for those fields, and in the caches
SetMillisecondsPerPixel(1); SetMillisecondsPerPixel(1);

View File

@ -54,6 +54,8 @@ class AudioRenderer;
/// @class AudioRendererBitmapCacheBitmapFactory /// @class AudioRendererBitmapCacheBitmapFactory
/// @brief Produces wxBitmap objects for DataBlockCache storage for the audio renderer /// @brief Produces wxBitmap objects for DataBlockCache storage for the audio renderer
struct AudioRendererBitmapCacheBitmapFactory { struct AudioRendererBitmapCacheBitmapFactory {
typedef std::unique_ptr<wxBitmap> BlockType;
/// The audio renderer we're producing bitmaps for /// The audio renderer we're producing bitmaps for
AudioRenderer *renderer; AudioRenderer *renderer;
@ -66,13 +68,7 @@ struct AudioRendererBitmapCacheBitmapFactory {
/// @return A fresh wxBitmap /// @return A fresh wxBitmap
/// ///
/// Produces a wxBitmap with dimensions pulled from our master AudioRenderer. /// Produces a wxBitmap with dimensions pulled from our master AudioRenderer.
wxBitmap *ProduceBlock(int i); std::unique_ptr<wxBitmap> ProduceBlock(int i);
/// @brief Delete a bitmap
/// @param bmp The bitmap to delete
///
/// Deletes said bitmap.
void DisposeBlock(wxBitmap *bmp);
/// @brief Calculate the size of bitmaps /// @brief Calculate the size of bitmaps
/// @return The size of bitmaps created /// @return The size of bitmaps created
@ -83,7 +79,6 @@ struct AudioRendererBitmapCacheBitmapFactory {
typedef DataBlockCache<wxBitmap, 8, AudioRendererBitmapCacheBitmapFactory> AudioRendererBitmapCache; typedef DataBlockCache<wxBitmap, 8, AudioRendererBitmapCacheBitmapFactory> AudioRendererBitmapCache;
/// @class AudioRenderer /// @class AudioRenderer
/// @brief Renders audio to bitmap images for display on screen /// @brief Renders audio to bitmap images for display on screen
/// ///

View File

@ -54,6 +54,8 @@
/// Allocates blocks of derived data for the audio spectrum /// Allocates blocks of derived data for the audio spectrum
struct AudioSpectrumCacheBlockFactory { struct AudioSpectrumCacheBlockFactory {
typedef std::unique_ptr<float, std::default_delete<float[]>> BlockType;
/// Pointer back to the owning spectrum renderer /// Pointer back to the owning spectrum renderer
AudioSpectrumRenderer *spectrum; AudioSpectrumRenderer *spectrum;
@ -66,18 +68,11 @@ struct AudioSpectrumCacheBlockFactory {
/// @return Newly allocated and filled block /// @return Newly allocated and filled block
/// ///
/// The filling is delegated to the spectrum renderer /// The filling is delegated to the spectrum renderer
float *ProduceBlock(size_t i) BlockType ProduceBlock(size_t i)
{ {
float *res = new float[((size_t)1)<<spectrum->derivation_size]; float *res = new float[((size_t)1)<<spectrum->derivation_size];
spectrum->FillBlock(i, res); spectrum->FillBlock(i, res);
return res; return BlockType(res);
}
/// @brief De-allocate a cache block
/// @param block The block to dispose of
void DisposeBlock(float *block)
{
delete[] block;
} }
/// @brief Calculate the in-memory size of a spec /// @brief Calculate the in-memory size of a spec
@ -118,7 +113,7 @@ AudioSpectrumRenderer::AudioSpectrumRenderer(std::string const& color_scheme_nam
AudioSpectrumRenderer::~AudioSpectrumRenderer() AudioSpectrumRenderer::~AudioSpectrumRenderer()
{ {
// This sequence will clean up // This sequence will clean up
provider = 0; provider = nullptr;
RecreateCache(); RecreateCache();
} }

View File

@ -307,7 +307,7 @@ namespace Automation4 {
std::string version; std::string version;
std::vector<cmd::Command*> macros; std::vector<cmd::Command*> macros;
std::vector<ExportFilter*> filters; std::vector<std::unique_ptr<ExportFilter>> filters;
/// load script and create internal structures etc. /// load script and create internal structures etc.
void Create(); void Create();
@ -337,7 +337,7 @@ namespace Automation4 {
bool GetLoadedState() const { return L != 0; } bool GetLoadedState() const { return L != 0; }
std::vector<cmd::Command*> GetMacros() const { return macros; } std::vector<cmd::Command*> GetMacros() const { return macros; }
std::vector<ExportFilter*> GetFilters() const { return filters; } std::vector<ExportFilter*> GetFilters() const;
std::vector<SubtitleFormat*> GetFormats() const { return std::vector<SubtitleFormat*>(); } std::vector<SubtitleFormat*> GetFormats() const { return std::vector<SubtitleFormat*>(); }
}; };
@ -492,12 +492,20 @@ namespace Automation4 {
for (int i = macros.size() - 1; i >= 0; --i) for (int i = macros.size() - 1; i >= 0; --i)
cmd::unreg(macros[i]->name()); cmd::unreg(macros[i]->name());
delete_clear(filters); filters.clear();
lua_close(L); lua_close(L);
L = nullptr; L = nullptr;
} }
std::vector<ExportFilter*> LuaScript::GetFilters() const
{
std::vector<ExportFilter *> ret;
ret.reserve(filters.size());
for (auto& filter : filters) ret.push_back(filter.get());
return ret;
}
void LuaScript::RegisterCommand(LuaCommand *command) void LuaScript::RegisterCommand(LuaCommand *command)
{ {
for (auto macro : macros) { for (auto macro : macros) {
@ -517,7 +525,7 @@ namespace Automation4 {
void LuaScript::RegisterFilter(LuaExportFilter *filter) void LuaScript::RegisterFilter(LuaExportFilter *filter)
{ {
filters.push_back(filter); filters.emplace_back(filter);
} }
LuaScript* LuaScript::GetScriptObject(lua_State *L) LuaScript* LuaScript::GetScriptObject(lua_State *L)

View File

@ -83,7 +83,7 @@ namespace Automation4 {
/// Commits to apply once processing completes successfully /// Commits to apply once processing completes successfully
std::deque<PendingCommit> pending_commits; std::deque<PendingCommit> pending_commits;
/// Lines to delete once processing complete successfully /// Lines to delete once processing complete successfully
std::deque<AssEntry*> lines_to_delete; std::deque<std::unique_ptr<AssEntry>> lines_to_delete;
int ObjectIndexRead(lua_State *L); int ObjectIndexRead(lua_State *L);
void ObjectIndexWrite(lua_State *L); void ObjectIndexWrite(lua_State *L);
@ -101,7 +101,7 @@ namespace Automation4 {
void LuaSetUndoPoint(lua_State *L); void LuaSetUndoPoint(lua_State *L);
// LuaAssFile can only be deleted by the reference count hitting zero // LuaAssFile can only be deleted by the reference count hitting zero
~LuaAssFile() { } ~LuaAssFile();
public: public:
static LuaAssFile *GetObjPointer(lua_State *L, int idx); static LuaAssFile *GetObjPointer(lua_State *L, int idx);

View File

@ -129,6 +129,8 @@ namespace {
} }
namespace Automation4 { namespace Automation4 {
LuaAssFile::~LuaAssFile() { }
void LuaAssFile::CheckAllowModify() void LuaAssFile::CheckAllowModify()
{ {
if (!can_modify) if (!can_modify)
@ -376,7 +378,7 @@ namespace Automation4 {
auto e = LuaToAssEntry(L); auto e = LuaToAssEntry(L);
modification_type |= modification_mask(e.get()); modification_type |= modification_mask(e.get());
CheckBounds(n); CheckBounds(n);
lines_to_delete.push_back(lines[n - 1]); lines_to_delete.emplace_back(lines[n - 1]);
lines[n - 1] = e.release(); lines[n - 1] = e.release();
} }
else { else {
@ -416,7 +418,7 @@ namespace Automation4 {
for (size_t i = 0; i < lines.size(); ++i) { for (size_t i = 0; i < lines.size(); ++i) {
if (id_idx < ids.size() && ids[id_idx] == i) { if (id_idx < ids.size() && ids[id_idx] == i) {
modification_type |= modification_mask(lines[i]); modification_type |= modification_mask(lines[i]);
lines_to_delete.push_back(lines[i]); lines_to_delete.emplace_back(lines[i]);
++id_idx; ++id_idx;
} }
else { else {
@ -438,7 +440,7 @@ namespace Automation4 {
for (; b < lines.size(); ++a, ++b) { for (; b < lines.size(); ++a, ++b) {
modification_type |= modification_mask(lines[a]); modification_type |= modification_mask(lines[a]);
lines_to_delete.push_back(lines[a]); lines_to_delete.emplace_back(lines[a]);
lines[a] = lines[b]; lines[a] = lines[b];
} }
@ -609,7 +611,7 @@ namespace Automation4 {
if (modification_type && can_set_undo && !undo_description.empty()) if (modification_type && can_set_undo && !undo_description.empty())
ass->Commit(undo_description, modification_type); ass->Commit(undo_description, modification_type);
delete_clear(lines_to_delete); lines_to_delete.clear();
references--; references--;
if (!references) delete this; if (!references) delete this;
@ -617,6 +619,7 @@ namespace Automation4 {
void LuaAssFile::Cancel() void LuaAssFile::Cancel()
{ {
for (auto& line : lines_to_delete) line.release();
references--; references--;
if (!references) delete this; if (!references) delete this;
} }

View File

@ -49,25 +49,18 @@
/// requested blocks in to avoid the default allocator. /// requested blocks in to avoid the default allocator.
template <typename BlockT> template <typename BlockT>
struct BasicDataBlockFactory { struct BasicDataBlockFactory {
typedef std::unique_ptr<BlockT> BlockType;
/// @brief Allocates a block and returns it /// @brief Allocates a block and returns it
/// @param i Index of the block to allocate /// @param i Index of the block to allocate
/// @return A pointer to the allocated block /// @return A pointer to the allocated block
/// ///
/// This default implementation does not use the i parameter. Custom implementations /// This default implementation does not use the i parameter. Custom implementations
/// of block factories should use i to determine what data to fill into the block. /// of block factories should use i to determine what data to fill into the block.
BlockT *ProduceBlock(size_t i) std::unique_ptr<BlockT> ProduceBlock(size_t i)
{ {
(void)i; (void)i;
return new BlockT; return std::unique_ptr<BlockT>(new BlockT);
}
/// @brief De-allocate a block
/// @param block Pointer to the block to de-allocate
///
/// It is guaranteed that block was returned by ProduceBlock.
void DisposeBlock(BlockT *block)
{
delete block;
} }
/// @brief Retrieve the amount of memory consumed by a single block /// @brief Retrieve the amount of memory consumed by a single block
@ -94,9 +87,8 @@ template <
typename BlockFactoryT = BasicDataBlockFactory<BlockT> typename BlockFactoryT = BasicDataBlockFactory<BlockT>
> >
class DataBlockCache { class DataBlockCache {
/// Type of an array of blocks /// Type of an array of blocks
typedef std::vector<BlockT*> BlockArray; typedef std::vector<typename BlockFactoryT::BlockType> BlockArray;
struct MacroBlock { struct MacroBlock {
/// This macroblock's position in the age list /// This macroblock's position in the age list
@ -105,6 +97,16 @@ class DataBlockCache {
/// The blocks contained in the macroblock /// The blocks contained in the macroblock
BlockArray blocks; BlockArray blocks;
#ifdef _MSC_VER
MacroBlock() { }
MacroBlock(MacroBlock&& rgt) : position(rgt.position), blocks(std::move(rgt.blocks)) { }
MacroBlock& operator=(MacroBlock&& rgt) {
position = rgt.position;
blocks = std::move(rgt.blocks);
return *this;
}
#endif
}; };
/// Type of an array of macro blocks /// Type of an array of macro blocks
@ -135,17 +137,21 @@ class DataBlockCache {
if (mb.blocks.empty()) if (mb.blocks.empty())
return; return;
for (auto block : mb.blocks)
{
if (block)
factory.DisposeBlock(block);
}
mb.blocks.clear(); mb.blocks.clear();
age.erase(mb.position); age.erase(mb.position);
} }
public: public:
#ifdef _MSC_VER
DataBlockCache(DataBlockCache&& rgt)
: data(std::move(rgt.data))
, age(std::move(rgt.age))
, macroblock_size(rgt.macroblock_size)
, macroblock_index_mask(rgt.macroblock_index_mask)
, factory(std::move(rgt.factory))
{ }
#endif
/// @brief Constructor /// @brief Constructor
/// @param block_count Total number of blocks the cache will manage /// @param block_count Total number of blocks the cache will manage
/// @param factory Factory object to use for producing blocks /// @param factory Factory object to use for producing blocks
@ -155,22 +161,12 @@ public:
/// ///
/// The factory object passed must respond well to copying. /// The factory object passed must respond well to copying.
DataBlockCache(size_t block_count, BlockFactoryT factory = BlockFactoryT()) DataBlockCache(size_t block_count, BlockFactoryT factory = BlockFactoryT())
: factory(factory) : factory(factory)
{ {
SetBlockCount(block_count); SetBlockCount(block_count);
} }
/// @brief Destructor
///
/// Disposes of all cached blocks
~DataBlockCache()
{
// Clear all blocks by aging to zero bytes
Age(0);
}
/// @brief Change the number of blocks in cache /// @brief Change the number of blocks in cache
/// @param block_count New number of blocks to hold /// @param block_count New number of blocks to hold
/// ///
@ -184,7 +180,7 @@ public:
macroblock_index_mask = ~(((~0) >> MacroblockExponent) << MacroblockExponent); macroblock_index_mask = ~(((~0) >> MacroblockExponent) << MacroblockExponent);
data.resize( (block_count + macroblock_size - 1) >> MacroblockExponent ); data.resize((block_count + macroblock_size - 1) >> MacroblockExponent);
} }
@ -201,8 +197,10 @@ public:
// Quick way out: get rid of everything // Quick way out: get rid of everything
if (max_size == 0) if (max_size == 0)
{ {
for (auto& mb : data) size_t block_count = data.size();
KillMacroBlock(mb); data.clear();
SetBlockCount(block_count);
age.clear();
return; return;
} }
@ -212,14 +210,12 @@ public:
auto it = age.begin(); auto it = age.begin();
for (; it != age.end() && cur_size < max_size; ++it) for (; it != age.end() && cur_size < max_size; ++it)
{ {
BlockArray &ba = (*it)->blocks; auto& ba = (*it)->blocks;
cur_size += (ba.size() - std::count(ba.begin(), ba.end(), nullptr)) * block_size; cur_size += (ba.size() - std::count(ba.begin(), ba.end(), nullptr)) * block_size;
} }
// Hit max, clear all remaining blocks // Hit max, clear all remaining blocks
for (; it != age.end();) for (; it != age.end(); )
{
KillMacroBlock(**it++); KillMacroBlock(**it++);
}
} }
@ -229,21 +225,17 @@ public:
/// @return A pointer to the block in cache /// @return A pointer to the block in cache
/// ///
/// It is legal to pass 0 (null) for created, in this case nothing is returned in it. /// It is legal to pass 0 (null) for created, in this case nothing is returned in it.
BlockT *Get(size_t i, bool *created = 0) BlockT *Get(size_t i, bool *created = nullptr)
{ {
size_t mbi = i >> MacroblockExponent; size_t mbi = i >> MacroblockExponent;
assert(mbi < data.size()); assert(mbi < data.size());
MacroBlock &mb = data[mbi]; MacroBlock &mb = data[mbi];
if (mb.blocks.size() == 0) if (mb.blocks.empty())
{
mb.blocks.resize(macroblock_size); mb.blocks.resize(macroblock_size);
}
else else
{
age.erase(mb.position); age.erase(mb.position);
}
// Move this macroblock to the front of the age list // Move this macroblock to the front of the age list
age.push_front(&mb); age.push_front(&mb);
@ -252,13 +244,13 @@ public:
size_t block_index = i & macroblock_index_mask; size_t block_index = i & macroblock_index_mask;
assert(block_index < mb.blocks.size()); assert(block_index < mb.blocks.size());
BlockT *b = mb.blocks[block_index]; BlockT *b = mb.blocks[block_index].get();
if (!b) if (!b)
{ {
b = factory.ProduceBlock(i); mb.blocks[block_index] = factory.ProduceBlock(i);
b = mb.blocks[block_index].get();
assert(b != 0); assert(b != 0);
mb.blocks[block_index] = b;
if (created) *created = true; if (created) *created = true;
} }

View File

@ -114,22 +114,6 @@ void SetClipboard(wxBitmap const& new_value);
#define countof(array) (sizeof(array) / sizeof(array[0])) #define countof(array) (sizeof(array) / sizeof(array[0]))
/// Polymorphic delete functor
struct delete_ptr {
template<class T> void operator()(T* ptr) const {
delete ptr;
}
};
/// Delete all of the items in a container of pointers and clear the container
template<class T>
void delete_clear(T& container) {
if (!container.empty()) {
std::for_each(container.begin(), container.end(), delete_ptr());
container.clear();
}
}
template<class Out> template<class Out>
struct cast { struct cast {
template<class In> template<class In>