Use a unique_ptr in agi::io::Save

This commit is contained in:
Thomas Goyne 2013-06-07 20:22:00 -07:00
parent f051e59a61
commit d81dfc1e73
3 changed files with 17 additions and 18 deletions

View File

@ -57,21 +57,15 @@ Save::Save(fs::path const& file, bool binary)
// Not an error
}
fp = new boost::filesystem::ofstream(tmp_name, binary ? std::ios::binary : std::ios::out);
if (!fp->good()) {
delete fp;
fp = util::make_unique<boost::filesystem::ofstream>(tmp_name, binary ? std::ios::binary : std::ios::out);
if (!fp->good())
throw fs::WriteDenied(tmp_name);
}
}
Save::~Save() {
delete fp; // Explicitly delete to unlock file on Windows
fp->close(); // Need to close before rename on Windows to unlock the file
fs::Rename(tmp_name, file_name);
}
std::ofstream& Save::Get() {
return *fp;
}
} // namespace io
} // namespace agi

View File

@ -32,14 +32,14 @@ DEFINE_SIMPLE_EXCEPTION_NOINNER(IOFatal, IOError, "io/fatal")
std::unique_ptr<std::ifstream> Open(fs::path const& file, bool binary = false);
class Save {
std::ofstream *fp;
std::unique_ptr<std::ofstream> fp;
const fs::path file_name;
const fs::path tmp_name;
public:
Save(fs::path const& file, bool binary = false);
~Save();
std::ofstream& Get();
std::ofstream& Get() { return *fp; }
};
} // namespace io

View File

@ -69,15 +69,20 @@ namespace agi {
/// @param name New name for the thread
void SetThreadName(const char *name);
template<typename T>
std::unique_ptr<T> make_unique() {
return std::unique_ptr<T>(new T);
#ifdef _MSC_VER
#define MAKE_UNIQUE(TEMPLATE_LIST, PADDING_LIST, LIST, COMMA, X1, X2, X3, X4) \
template<class T COMMA LIST(_CLASS_TYPE)> \
inline std::unique_ptr<T> make_unique(LIST(_TYPE_REFREF_ARG)) { \
return std::unique_ptr<T>(new T(LIST(_FORWARD_ARG))); \
}
template<typename T, typename A1>
std::unique_ptr<T> make_unique(A1&& a1) {
return std::unique_ptr<T>(new T(std::forward<A1>(a1)));
_VARIADIC_EXPAND_0X(MAKE_UNIQUE, , , , )
#undef MAKE_UNIQUE
#else
template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args) {
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
#endif
} // namespace util
} // namespace agi