Last active
August 29, 2015 14:16
-
-
Save firegurafiku/cfb1bd997e9d7addd777 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <memory> | |
namespace rvlm { | |
template<typename T> | |
class object_ptr: public std::shared_ptr<T> { | |
public: | |
object_ptr(const object_ptr&) noexcept = default; | |
template<typename T1, typename = | |
typename std::enable_if<std::is_convertible<T1*, T*>::value>::type> | |
object_ptr(const object_ptr<T1>& r) noexcept | |
: std::shared_ptr<T>(r) { } | |
object_ptr(object_ptr<T>&& r) noexcept | |
: std::shared_ptr<T>(std::move(r)) { } | |
template<typename T1, typename = | |
typename std::enable_if<std::is_convertible<T1*, T*>::value>::type> | |
object_ptr(object_ptr<T1>&& r) noexcept | |
: std::shared_ptr<T>(std::move(r)) { } | |
object_ptr& operator=(const object_ptr&) noexcept = default; | |
template<typename T1> | |
object_ptr& operator=(const object_ptr<T1>& r) noexcept { | |
this->std::shared_ptr<T>::operator=(r); | |
return *this; | |
} | |
object_ptr& operator=(object_ptr&& r) noexcept { | |
this->std::shared_ptr<T>::operator=(std::move(r)); | |
return *this; | |
} | |
template<class T1> | |
object_ptr& operator=(object_ptr<T1>&& r) noexcept { | |
this->std::shared_ptr<T>::operator=(std::move(r)); | |
return *this; | |
} | |
private: | |
void check_not_null(const std::shared_ptr<T>& p) { | |
if (!p) | |
throw std::bad_alloc(); | |
} | |
object_ptr(const std::shared_ptr<T>& p) { | |
check_not_null(p); | |
} | |
template <typename T1, typename TAlloc, typename... TArgs> | |
friend object_ptr<T1> allocate_object(const TAlloc& a, TArgs&&... args); | |
template <typename T1, typename... TArgs> | |
friend object_ptr<T1> make_object(TArgs&&... args); | |
}; | |
template <typename T, typename TAlloc, typename... TArgs> | |
object_ptr<T> allocate_object(const TAlloc& a, TArgs&&... args) { | |
return object_ptr<T>( | |
std::allocate_shared<T>(a, std::forward<TArgs>(args)...)); | |
} | |
template <typename T, typename... TArgs> | |
object_ptr<T> make_object(TArgs&&... args) { | |
return object_ptr<T>(std::make_shared<T>(std::forward<TArgs>(args)...)); | |
} | |
} // namespace rvlm |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "catch.hpp" | |
#include "rvlm/object_ptr.hh" | |
class TestClass { | |
public: | |
int mInt; | |
float mFloat; | |
TestClass(): mInt(0), mFloat(0) {} | |
TestClass(int a): mInt(a) {} | |
TestClass(int a, float b): mInt(a), mFloat(b) {} | |
}; | |
TEST_CASE("Works", "rvlm::object_ptr") { | |
SECTION("Default construction") { | |
auto obj1 = rvlm::make_object<TestClass>(); | |
auto obj2 = rvlm::make_object<TestClass>(1); | |
auto obj3 = rvlm::make_object<TestClass>(1, 1.0f); | |
REQUIRE(typeid(obj1) == typeid(obj2)); | |
REQUIRE(typeid(obj2) == typeid(obj3)); | |
REQUIRE(typeid(obj3) == typeid(obj1)); | |
} | |
SECTION("Copying") { | |
auto obj1 = rvlm::make_object<TestClass>(); | |
auto obj2 = obj2; | |
REQUIRE(obj1 == obj2); | |
} | |
SECTION("Dereferencing") { | |
auto obj = rvlm::make_object<TestClass>(1, 2); | |
REQUIRE(obj->mInt, 1); | |
REQUIRE(bbj->mFloat, 2); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment