Required C++ language version is now C++14.
build_info
{
threads true;
- standard CXX "c++11";
+ standard CXX "c++14";
};
if_arch "linux"
{
namespace Msp {
-Application *Application::_app = nullptr;
+unique_ptr<Application> Application::_app;
Application::Starter *Application::_starter = nullptr;
const char *Application::_argv0 = nullptr;
string Application::_name;
created_callback(data);
int result = _app->main();
- Application *a = _app;
- _app = nullptr;
- delete a;
+ unique_ptr<Application> a = move(_app);
return result;
}
catch(const exception &e)
}
}
- delete _app;
_app = nullptr;
return 124;
#ifndef MSP_CORE_APPLICATION_H_
#define MSP_CORE_APPLICATION_H_
+#include <memory>
#include <stdexcept>
#include <string>
#include "mspcore_api.h"
public:
virtual ~Starter() = default;
- virtual Application *create_app(int, char **) = 0;
+ virtual std::unique_ptr<Application> create_app(int, char **) = 0;
};
bool done = false;
private:
static Starter *_starter;
- static Application *_app;
+ static std::unique_ptr<Application> _app;
static const char *_argv0;
static std::string _name;
static void *_data;
class Starter: public Application::Starter
{
public:
- Application *create_app(int argc, char **argv) { return new T(argc, argv); }
+ std::unique_ptr<Application> create_app(int argc, char **argv) { return std::make_unique<T>(argc, argv); }
};
static Starter _starter;
add_option("help", help, NO_ARG).set_help("Displays this help");
}
-GetOpt::~GetOpt()
-{
- for(OptionImpl *i: opts)
- delete i;
- for(ArgumentImpl *i: args)
- delete i;
-}
-
GetOpt::OptionImpl &GetOpt::add_option(char s, const string &l, const Store &t, ArgType a)
{
if(l.empty())
for(auto i=opts.begin(); i!=opts.end(); )
{
if((s!=0 && (*i)->get_short()==s) || (*i)->get_long()==l)
- {
- delete *i;
i = opts.erase(i);
- }
else
++i;
}
- opts.push_back(new OptionImpl(s, l, t, a));
+ opts.push_back(make_unique<OptionImpl>(s, l, t, a));
return *opts.back();
}
bool have_list = false;
bool have_optional = false;
- for(const ArgumentImpl *a: args)
+ for(const unique_ptr<ArgumentImpl> &a: args)
{
if(a->is_list_store())
have_list = true;
if(have_list && (t.is_list() || y==OPTIONAL_ARG))
throw invalid_argument("GetOpt::add_argument");
- args.push_back(new ArgumentImpl(n, t, y));
+ args.push_back(make_unique<ArgumentImpl>(n, t, y));
return *args.back();
}
GetOpt::OptionImpl &GetOpt::get_option(char s)
{
- auto i = find_if(opts, [s](const OptionImpl *o){ return o->get_short()==s; });
+ auto i = find_if(opts, [s](const unique_ptr<OptionImpl> &o){ return o->get_short()==s; });
if(i!=opts.end())
return **i;
throw usage_error(string("Unknown option -")+s);
GetOpt::OptionImpl &GetOpt::get_option(const string &l)
{
- auto i = find_if(opts, [&l](const OptionImpl *o){ return o->get_long()==l; });
+ auto i = find_if(opts, [&l](const unique_ptr<OptionImpl> &o){ return o->get_long()==l; });
if(i!=opts.end())
return **i;
throw usage_error(string("Unknown option --")+l);
result += " [options]";
else
{
- for(const OptionImpl *o: opts)
+ for(const unique_ptr<OptionImpl> &o: opts)
{
result += " [";
if(o->get_short())
}
}
- for(const ArgumentImpl *a: args)
+ for(const unique_ptr<ArgumentImpl> &a: args)
{
result += ' ';
if(a->get_type()==OPTIONAL_ARG)
string GetOpt::generate_help() const
{
- bool any_short = any_of(opts.begin(), opts.end(), [](const OptionImpl *o){ return o->get_short(); });
+ bool any_short = any_of(opts.begin(), opts.end(), [](const unique_ptr<OptionImpl> &o){ return o->get_short(); });
string::size_type maxw = 0;
vector<string> switches;
- for(const OptionImpl *o: opts)
+ for(const unique_ptr<OptionImpl> &o: opts)
{
string swtch;
if(o->get_short())
}
vector<string> pargs;
- for(const ArgumentImpl *a: args)
+ for(const unique_ptr<ArgumentImpl> &a: args)
{
string parg = format("<%s>", a->get_name());
pargs.push_back(parg);
store(t.clone())
{ }
-GetOpt::OptionImpl::~OptionImpl()
-{
- delete store;
-}
-
GetOpt::OptionImpl &GetOpt::OptionImpl::set_help(const string &h)
{
help = h;
store(t.clone())
{ }
-GetOpt::ArgumentImpl::~ArgumentImpl()
-{
- delete store;
-}
-
GetOpt::ArgumentImpl &GetOpt::ArgumentImpl::set_help(const string &h)
{
help = h;
#define MSP_CORE_GETOPT_H_
#include <list>
+#include <memory>
#include <stdexcept>
#include <string>
#include <vector>
public:
virtual ~Store() = default;
- virtual Store *clone() const = 0;
+ virtual std::unique_ptr<Store> clone() const = 0;
virtual bool is_list() const = 0;
virtual void store() = 0;
unsigned *ext_seen_count = nullptr;
std::string help;
std::string metavar = "ARG";
- Store *store = nullptr;
+ std::unique_ptr<Store> store;
public:
OptionImpl(char, const std::string &, const Store &, ArgType);
- ~OptionImpl() override;
OptionImpl &set_help(const std::string &) override;
OptionImpl &set_help(const std::string &, const std::string &) override;
std::string name;
ArgType type = REQUIRED_ARG;
std::string help;
- Store *store = nullptr;
+ std::unique_ptr<Store> store;
public:
ArgumentImpl(const std::string &, const Store &, ArgType);
- ~ArgumentImpl() override;
ArgumentImpl &set_help(const std::string &) override;
const std::string &get_name() const { return name; }
public:
SimpleStore(T &d): data(d) { }
- SimpleStore *clone() const override
- { return new SimpleStore(data); }
+ std::unique_ptr<Store> clone() const override { return std::make_unique<SimpleStore>(data); }
bool is_list() const override { return false; }
public:
ListStore(T &d): data(d) { }
- ListStore *clone() const override
- { return new ListStore(data); }
+ std::unique_ptr<Store> clone() const override { return std::make_unique<ListStore>(data); }
bool is_list() const override { return true; }
};
bool help = false;
- std::vector<OptionImpl *> opts;
- std::vector<ArgumentImpl *> args;
+ std::vector<std::unique_ptr<OptionImpl>> opts;
+ std::vector<std::unique_ptr<ArgumentImpl>> args;
std::vector<std::string> args_raw;
public:
GetOpt();
- ~GetOpt();
/** Adds an option with both short and long forms. Processing depends on
the type of the destination variable and whether an argument is taken or
namespace Msp {
-Process *Process::_self = nullptr;
+unique_ptr<Process> Process::_self;
Process::Process(const Private &p):
priv(new Private(p))
{
Private _priv;
platform_get_self_info(_priv);
- _self = new Process(_priv);
+ _self = unique_ptr<Process>(new Process(_priv));
}
return *_self;
}
void Process::do_redirect(IO::Base *&ptr, IO::Base &io)
{
- if(this==_self)
+ if(this==_self.get())
{
if(&ptr==&cin)
IO::cin.redirect(io);
#ifndef MSP_CORE_PROCESS_H_
#define MSP_CORE_PROCESS_H_
+#include <memory>
#include <string>
#include <vector>
#include <msp/fs/path.h>
bool finished = false;
unsigned exit_code = 0;
- static Process *_self;
+ static std::unique_ptr<Process> _self;
Process(const Private &);
public:
#define MSP_CORE_TYPEREGISTRY_H_
#include <map>
+#include <memory>
#include <string>
#include "maputils.h"
#include "noncopyable.h"
void invoke(T arg) const override { action(this->keyword, arg); }
};
- std::map<std::string, TypeBase *> types;
+ std::map<std::string, std::unique_ptr<TypeBase>> types;
public:
- ~TypeRegistry();
-
/** Registers a type. */
template<typename R>
void register_type(const std::string &);
void invoke_all(T) const;
};
-template<template<typename> class A, typename T>
-TypeRegistry<A, T>::~TypeRegistry()
-{
- for(auto &kvp: types)
- delete kvp.second;
-}
-
template<template<typename> class A, typename T>
template<typename R>
void TypeRegistry<A, T>::register_type(const std::string &kw)
if(types.count(kw))
throw key_error(kw);
- types[kw] = new RegisteredType<R>(kw);
+ types[kw] = std::make_unique<RegisteredType<R>>(kw);
}
template<template<typename> class A, typename T>
void Process::execute(const string &command, bool path_search, const Arguments &args)
{
pid_t pid = 0;
- if(this!=_self)
+ if(this!=_self.get())
pid = fork();
if(pid==-1)
running = true;
- if(this==_self)
+ if(this==_self.get())
TerminateProcess(priv->info.hProcess, 0);
}
Base::~Base()
{
signal_deleted.emit();
- delete mutex;
}
void Base::check_access(Mode m) const
io(i)
{
if(!io.mutex)
- io.mutex = new Mutex;
+ io.mutex = make_unique<Mutex>();
io.mutex->lock();
}
#define MSP_IO_BASE_H_
#include <cstddef>
+#include <memory>
#include <sigc++/sigc++.h>
#include <msp/core/mspcore_api.h>
#include <msp/core/mutex.h>
protected:
Mode mode = M_READ;
bool eof_flag = false;
- Mutex *mutex = nullptr;
+ std::unique_ptr<Mutex> mutex;
Base();
public:
struct Asset::Private
{
- Seekable *file;
+ unique_ptr<Seekable> file;
};
Asset::Asset(const string &name)
{
- Seekable *file = new BufferedFile((FS::get_sys_data_dir()/name).str());
+ unique_ptr<Seekable> file = make_unique<BufferedFile>((FS::get_sys_data_dir()/name).str());
priv = new Private;
- priv->file = file;
+ priv->file = move(file);
priv->file->signal_flush_required.connect(signal_flush_required);
}
Asset::~Asset()
{
- delete priv->file;
delete priv;
}
bool Codec::detect(const string &str) const
{
- Decoder *dec = create_decoder(IGNORE_ERRORS);
+ unique_ptr<Decoder> dec = create_decoder(IGNORE_ERRORS);
bool result = true;
for(auto i=str.begin(); (result && i!=str.end()); )
result = (dec->decode_char(str, i)!=-1);
- delete dec;
-
return result;
}
return buf;
}
-Codec *create_codec(const string &n)
+unique_ptr<Codec> create_codec(const string &n)
{
string name;
string::const_iterator i;
throw invalid_argument("StringCodec::create_codec");
}
- if(name=="ascii") return new Ascii(em);
- if(name=="iso2022jp") return new Iso2022Jp(em);
- if(name=="iso646fi") return new Iso646Fi(em);
- if(name=="iso88591" || name=="latin1") return new Iso88591(em);
- if(name=="iso885915" || name=="latin9") return new Iso885915(em);
- if(name=="jisx0201") return new JisX0201(em);
- if(name=="jisx0208") return new JisX0208(em);
- if(name=="utf8") return new Utf8(em);
- if(name=="utf16") return new Utf16(em, Utf16::AUTO);
- if(name=="utf16be") return new Utf16(em, Utf16::BIG);
- if(name=="utf16le") return new Utf16(em, Utf16::LITTLE);
- if(name=="windows1252" || name=="cp1252") return new Windows1252(em);
+ if(name=="ascii") return make_unique<Ascii>(em);
+ if(name=="iso2022jp") return make_unique<Iso2022Jp>(em);
+ if(name=="iso646fi") return make_unique<Iso646Fi>(em);
+ if(name=="iso88591" || name=="latin1") return make_unique<Iso88591>(em);
+ if(name=="iso885915" || name=="latin9") return make_unique<Iso885915>(em);
+ if(name=="jisx0201") return make_unique<JisX0201>(em);
+ if(name=="jisx0208") return make_unique<JisX0208>(em);
+ if(name=="utf8") return make_unique<Utf8>(em);
+ if(name=="utf16") return make_unique<Utf16>(em, Utf16::AUTO);
+ if(name=="utf16be") return make_unique<Utf16>(em, Utf16::BIG);
+ if(name=="utf16le") return make_unique<Utf16>(em, Utf16::LITTLE);
+ if(name=="windows1252" || name=="cp1252") return make_unique<Windows1252>(em);
throw invalid_argument("StringCodec::create_codec");
}
-Codec *detect_codec(const string &str)
+unique_ptr<Codec> detect_codec(const string &str)
{
bool is_utf8 = true;
bool is_ascii = true;
}
if(is_ascii)
- return new Ascii;
+ return make_unique<Ascii>();
else if(is_utf8)
- return new Utf8;
+ return make_unique<Utf8>();
else if(is_latin1)
- return new Iso88591;
+ return make_unique<Iso88591>();
else
- return new Windows1252;
+ return make_unique<Windows1252>();
}
} // namespace StringCodec
#ifndef MSP_STRINGCODEC_CODEC_H_
#define MSP_STRINGCODEC_CODEC_H_
+#include <memory>
#include <string>
#include <msp/core/mspcore_api.h>
#include "except.h"
virtual const char *get_name() const = 0;
/** Creates an encoder for this codec. */
- virtual Encoder *create_encoder(ErrorMode err_mode = DEFAULT) const = 0;
+ virtual std::unique_ptr<Encoder> create_encoder(ErrorMode err_mode = DEFAULT) const = 0;
/** Creates a decoder for this codec. */
- virtual Decoder *create_decoder(ErrorMode err_mode = DEFAULT) const = 0;
+ virtual std::unique_ptr<Decoder> create_decoder(ErrorMode err_mode = DEFAULT) const = 0;
/** Determines whether the given string can be successfully decoded with
this codec. Note that this function returning true does not guarantee that
{ return (em==DEFAULT ? err_mode : em); }
public:
- Encoder *create_encoder(ErrorMode em = DEFAULT) const override
- { return new typename C::Encoder(get_error_mode(em)); }
+ std::unique_ptr<Encoder> create_encoder(ErrorMode em = DEFAULT) const override
+ { return std::make_unique<typename C::Encoder>(get_error_mode(em)); }
- Decoder *create_decoder(ErrorMode em = DEFAULT) const override
- { return new typename C::Decoder(get_error_mode(em)); }
+ std::unique_ptr<Decoder> create_decoder(ErrorMode em = DEFAULT) const override
+ { return std::make_unique<typename C::Decoder>(get_error_mode(em)); }
};
return encode<T>(decode<F>(s));
}
-/** Creates a codec for an encoding by name. The caller is responsible for
-deleting the codec when it's no longer needed. */
-MSPCORE_API Codec *create_codec(const std::string &);
+/** Creates a codec for an encoding by name. */
+MSPCORE_API std::unique_ptr<Codec> create_codec(const std::string &);
-/** Automatically detects the encoding of a string and creates a codec for it.
-The codec must be deleted when it's no longer needed. */
-MSPCORE_API Codec *detect_codec(const std::string &);
+/** Automatically detects the encoding of a string and creates a codec for it. */
+MSPCORE_API std::unique_ptr<Codec> detect_codec(const std::string &);
} // namespace StringCodec
} // namespace Msp
Iso2022Jp::Decoder::Decoder(ErrorMode em):
Codec::Decoder(em),
- dec(new Ascii::Decoder)
+ dec(make_unique<Ascii::Decoder>())
{ }
unichar Iso2022Jp::Decoder::decode_char(const string &str, string::const_iterator &i)
void Iso2022Jp::Decoder::reset()
{
- delete dec;
mode = ASCII;
- dec = new Ascii::Decoder;
+ dec = make_unique<Ascii::Decoder>();
}
void Iso2022Jp::Decoder::switch_mode(Mode m)
{
- delete dec;
-
mode = m;
switch(mode)
{
- case ASCII: dec = new Ascii::Decoder; break;
- case JISX0201: dec = new JisX0201::Decoder; break;
- case JISX0208: dec = new JisX0208::Decoder; break;
+ case ASCII: dec = make_unique<Ascii::Decoder>(); break;
+ case JISX0201: dec = make_unique<JisX0201::Decoder>(); break;
+ case JISX0208: dec = make_unique<JisX0208::Decoder>(); break;
}
}
{
private:
Mode mode = ASCII;
- Codec::Decoder *dec = nullptr;
+ std::unique_ptr<Codec::Decoder> dec;
public:
Decoder(ErrorMode = DEFAULT);
const char *get_name() const override
{ return endian==BIG ? "UTF-16-BE" : endian==LITTLE ? "UTF-16-LE" : "UTF-16"; }
- Encoder *create_encoder(ErrorMode em = DEFAULT) const override
- { return new Encoder(get_error_mode(em), endian); }
+ std::unique_ptr<Codec::Encoder> create_encoder(ErrorMode em = DEFAULT) const override
+ { return std::make_unique<Encoder>(get_error_mode(em), endian); }
- Decoder *create_decoder(ErrorMode em = DEFAULT) const override
- { return new Decoder(get_error_mode(em), endian); }
+ std::unique_ptr<Codec::Decoder> create_decoder(ErrorMode em = DEFAULT) const override
+ { return std::make_unique<Decoder>(get_error_mode(em), endian); }
};
sem(1)
{ }
-Timer::~Timer()
-{
- for(const SlotProxy &s: slots)
- delete s.slot;
-}
-
Timer::Slot &Timer::add(const TimeDelta &td)
{
- Slot *s = new Slot(td);
+ unique_ptr<Slot> s = make_unique<Slot>(td);
+ Slot &sref = *s;
MutexLock l(mutex);
- slots.push_back({ s });
+ slots.push_back({ move(s) });
push_heap(slots.begin(), slots.end());
if(blocking)
sem.signal();
- return *s;
+ return sref;
}
Timer::Slot &Timer::add(const TimeStamp &ts)
{
- Slot *s = new Slot(ts);
+ unique_ptr<Slot> s = make_unique<Slot>(ts);
+ Slot &sref = *s;
MutexLock l(mutex);
- slots.push_back({ s });
+ slots.push_back({ move(s) });
push_heap(slots.begin(), slots.end());
if(blocking)
sem.signal();
- return *s;
+ return sref;
}
void Timer::cancel(Slot &slot)
{
MutexLock l(mutex);
- auto i = find_member(slots, &slot, &SlotProxy::slot);
+ auto i = find_if(slots, [&slot](const SlotProxy &p){ return p.slot.get()==&slot; });
if(i!=slots.end())
{
- delete i->slot;
slots.erase(i);
make_heap(slots.begin(), slots.end());
}
if(timeout>=zero)
deadline = now()+timeout;
- Slot *next = nullptr;
+ unique_ptr<Slot> next;
{
MutexLock l(mutex);
while(1)
TimeStamp t = now();
if(!slots.empty())
{
- next = slots.begin()->slot;
- stamp = next->get_timeout();
+ stamp = slots.front().slot->get_timeout();
if(stamp<=t)
break;
}
return;
}
+ next = move(slots.front().slot);
pop_heap(slots.begin(), slots.end());
slots.pop_back();
}
- try
- {
- if(next->signal_timeout.emit() && next->increment())
- {
- MutexLock l(mutex);
- slots.push_back({ next });
- push_heap(slots.begin(), slots.end());
- }
- else
- delete next;
- }
- catch(...)
+ if(next->signal_timeout.emit() && next->increment())
{
- delete next;
- throw;
+ MutexLock l(mutex);
+ slots.push_back({ move(next) });
+ push_heap(slots.begin(), slots.end());
}
}
#ifndef MSP_TIME_TIMER_H_
#define MSP_TIME_TIMER_H_
+#include <memory>
#include <vector>
#include <sigc++/sigc++.h>
#include <msp/core/mspcore_api.h>
private:
struct SlotProxy
{
- Slot *slot;
+ std::unique_ptr<Slot> slot;
bool operator<(const SlotProxy &) const;
};
public:
Timer();
- ~Timer();
/** Adds a timer that will be executed periodically as long as the timeout
signal hander returns true. */