You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
90 lines
2.8 KiB
90 lines
2.8 KiB
2 years ago
|
#ifndef MEDUSA_BITS_UTILS_MEMUTILS_HPP_
|
||
|
#define MEDUSA_BITS_UTILS_MEMUTILS_HPP_
|
||
|
|
||
|
/**
|
||
|
* @file
|
||
|
* Declaration of memory related utilities.
|
||
|
*
|
||
|
* @example test/utils/memutils_test.cpp
|
||
|
*/
|
||
|
|
||
|
#include <memory>
|
||
|
#include <medusa/Config.hpp>
|
||
|
#include <medusa/bits/utils/assert.hpp>
|
||
|
|
||
|
namespace mm {
|
||
|
|
||
|
/**
|
||
|
* Unique pointer with polymorphic deep copy semantics. It is copy constructible and
|
||
|
* copy assignable. Copy construction creates a new pointer, containing a clone
|
||
|
* of the object, the original pointer pointed to.
|
||
|
* @tparam T Value type. Must be polymorphically cloneable, i.e.\ have a virtual `clone` method
|
||
|
* as example below.
|
||
|
*
|
||
|
* Usage example:
|
||
|
* @snippet utils/memutils_test.cpp deep_copy_unique_ptr def
|
||
|
* @snippet utils/memutils_test.cpp deep_copy_unique_ptr usage
|
||
|
* @ingroup utils
|
||
|
*/
|
||
|
template <typename T>
|
||
|
class deep_copy_unique_ptr : public std::unique_ptr<T, std::default_delete<T>> {
|
||
|
public:
|
||
|
using std::unique_ptr<T, std::default_delete<T>>::unique_ptr;
|
||
|
using std::unique_ptr<T, std::default_delete<T>>::operator=;
|
||
|
using std::unique_ptr<T, std::default_delete<T>>::reset;
|
||
|
|
||
|
/// Construct by polymorphically cloning a given value.
|
||
|
explicit deep_copy_unique_ptr(const T& v) :
|
||
|
std::unique_ptr<T, std::default_delete<T>>(v.clone()) {}
|
||
|
|
||
|
/// Copy by cloning the value of `o`.
|
||
|
deep_copy_unique_ptr(const deep_copy_unique_ptr& o) :
|
||
|
std::unique_ptr<T, std::default_delete<T>>() {
|
||
|
reset(o ? o->clone() : nullptr);
|
||
|
}
|
||
|
|
||
|
/// Move construct as `unique_ptr`.
|
||
|
deep_copy_unique_ptr(deep_copy_unique_ptr&& o) noexcept :
|
||
|
std::unique_ptr<T, std::default_delete<T>>(std::move(o)) { }
|
||
|
|
||
|
/// Copy assign by cloning a given value.
|
||
|
deep_copy_unique_ptr& operator=(const T& v) {
|
||
|
reset(v.clone());
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
/// Copy assign by cloning the value of `o`.
|
||
|
deep_copy_unique_ptr& operator=(const deep_copy_unique_ptr& o) {
|
||
|
reset(o ? o->clone() : nullptr);
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
/// Move assign as `unique_ptr`
|
||
|
deep_copy_unique_ptr& operator=(deep_copy_unique_ptr&& o) noexcept {
|
||
|
std::unique_ptr<T, std::default_delete<T>>::operator=(std::move(o));
|
||
|
return *this;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Simple function to help format memory amounts for printing. Takes in number of bytes
|
||
|
* and returns a human readable representation.
|
||
|
* @ingroup utils
|
||
|
*/
|
||
|
std::string mem2str(std::size_t bytes);
|
||
|
|
||
|
/**
|
||
|
* Returns number of bytes the container uses in memory. The container must support `size()`.
|
||
|
* This does not count the memory that may be allocated by objects stored in the container.
|
||
|
* Also STL containers like vector may actually have more memory allocated than their size.
|
||
|
* @ingroup utils
|
||
|
*/
|
||
|
template<typename container_t>
|
||
|
std::size_t mem_used(const container_t& v) {
|
||
|
return sizeof(v[0]) * v.size();
|
||
|
}
|
||
|
|
||
|
} // namespace mm
|
||
|
|
||
|
#endif // MEDUSA_BITS_UTILS_MEMUTILS_HPP_
|