diff --git a/alib2std/src/extensions/memory.hpp b/alib2std/src/extensions/memory.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..5e39fdbb3471f12d80f9590088f8bb05b75c28ba
--- /dev/null
+++ b/alib2std/src/extensions/memory.hpp
@@ -0,0 +1,123 @@
+#ifndef _MEMORY_HPP__
+#define _MEMORY_HPP__
+
+namespace std {
+
+template<class T>
+class cow_shared_ptr {
+	struct cow_shared_ptr_data {
+		T * m_Data;
+		int m_UseCount;
+		cow_shared_ptr_data ( T * data ) : m_Data ( data ), m_UseCount( 0 ) { }
+		~cow_shared_ptr_data ( ) {
+			delete m_Data;
+		}
+	};
+
+public:
+	cow_shared_ptr ( ) {
+		attach ( NULL );
+	}
+
+	cow_shared_ptr ( T * data ) {
+		attach ( new cow_shared_ptr_data( data ) );
+	}
+
+	cow_shared_ptr ( const cow_shared_ptr<T> & other ) {
+		attach ( other.m_Data );
+	}
+
+	cow_shared_ptr ( cow_shared_ptr<T> && other ) noexcept {
+		attach ( other.m_Data );
+	}
+
+	~cow_shared_ptr ( ) noexcept {
+		deattach ( );
+	}
+
+	cow_shared_ptr<T> & operator = ( const cow_shared_ptr<T> & other ) {
+		if(this == &other) return *this;
+
+		deattach ( );
+		attach ( other.m_Data );
+
+		return *this;
+	}
+
+	cow_shared_ptr<T> & operator = ( cow_shared_ptr<T> && other ) noexcept {
+		swap(*this, other);
+		return *this;
+	}
+
+	T * operator -> ( ) {
+		make_unique( );
+		return m_Data->m_Data;
+	}
+
+	T const * operator -> ( ) const {
+		return m_Data->m_Data;
+	}
+
+	T & operator * ( ) {
+		make_unique( );
+		return *(m_Data->m_Data);
+	}
+
+	T const & operator * ( ) const {
+		return *(m_Data->m_Data);
+	}
+
+	T * get () {
+		make_unique( );
+		return m_Data->m_Data;
+	}
+
+	T const * get () const {
+		return m_Data->m_Data;
+	}
+
+	bool unique ( ) const {
+		return m_Data == NULL || m_Data->m_UseCount == 1; 
+	}
+
+private:
+	void attach ( cow_shared_ptr<T>::cow_shared_ptr_data * data ) {
+		m_Data = data;
+		if(m_Data) m_Data->m_UseCount++;
+	}
+
+	void deattach ( ) {
+		if(m_Data && --(m_Data->m_UseCount) <= 0) delete m_Data;
+		m_Data = NULL;
+	}
+
+	void make_unique( ) {
+		if(unique( )) return;
+
+		typename cow_shared_ptr<T>::cow_shared_ptr_data* tmp = m_Data;
+		deattach( );
+		attach(new cow_shared_ptr_data(new T(*(tmp->m_Data))));
+	}
+
+	cow_shared_ptr_data * m_Data;
+
+	friend void swap ( cow_shared_ptr<T> & first, cow_shared_ptr<T> & second ) {
+		typename cow_shared_ptr<T>::cow_shared_ptr_data* tmp = first.m_Data;
+		first.m_Data = second.m_Data;
+		second.m_Data = tmp;
+	}
+};
+
+template<class T>
+const cow_shared_ptr<T>& make_const(cow_shared_ptr<T>& ptr) {
+	return static_cast<const cow_shared_ptr<T>&>(ptr);
+}
+
+template<class T>
+const cow_shared_ptr<T>& make_const(const cow_shared_ptr<T>& ptr) {
+	return ptr;
+}
+
+} /* namespace std */
+
+#endif // _MEMORY_HPP__
diff --git a/alib2std/src/memory b/alib2std/src/memory
new file mode 100644
index 0000000000000000000000000000000000000000..1d4b97f7375d7ca82c4167abb6d24f2610dfc0d4
--- /dev/null
+++ b/alib2std/src/memory
@@ -0,0 +1,7 @@
+#ifndef __MEMORY_HEADER_WRAPPER_
+#define __MEMORY_HEADER_WRAPPER_
+
+#include <bits/../memory>
+#include "extensions/memory.hpp"
+
+#endif /* __MEMORY_HEADER_WRAPPER_ */
diff --git a/alib2std/test-src/extensions/SetTest.cpp b/alib2std/test-src/extensions/SetTest.cpp
index 712b4cd16afb6bdc66402cdcf8392928b1439e60..15ffd03fe0954887cf73e342c66d5f9f4ffb0c10 100644
--- a/alib2std/test-src/extensions/SetTest.cpp
+++ b/alib2std/test-src/extensions/SetTest.cpp
@@ -43,35 +43,12 @@ void SetTest::test2() {
 	CPPUNIT_ASSERT_EQUAL(secondMinusFirst.size(), 2ul);
 }
 
-class Moveable {
-	int& moves;
-	int& copies;
-
-public:
-	Moveable(int& moves, int& copies) : moves(moves), copies(copies) {
-		moves = 0;
-		copies = 0;
-	}
-
-	Moveable(const Moveable& src) : moves(src.moves), copies(src.copies) {
-		copies++;
-	}
-
-	Moveable(Moveable&& src) : moves(src.moves), copies(src.copies) {
-		moves++;
-	}
-
-	bool operator<(const Moveable&) const {
-		return false;
-	}
-};
-
 void SetTest::test3() {
 	int moves;
 	int copies;
 
-	std::set<Moveable> set = {Moveable(moves, copies)};
-	std::set<Moveable> set2;
+	std::set<SetTest::Moveable> set = {SetTest::Moveable(moves, copies)};
+	std::set<SetTest::Moveable> set2;
 
 	for(Moveable moveable : std::make_moveable_set(set)) {
 		set2.insert(std::move(moveable));
diff --git a/alib2std/test-src/extensions/SetTest.h b/alib2std/test-src/extensions/SetTest.h
index ce6f31b5ee5f0f9cfd1747dd6d7fd42c36c4d821..91091fa046505b2111484df75d2c4bd6e53169aa 100644
--- a/alib2std/test-src/extensions/SetTest.h
+++ b/alib2std/test-src/extensions/SetTest.h
@@ -10,6 +10,30 @@ class SetTest : public CppUnit::TestFixture
   CPPUNIT_TEST( test2 );
   CPPUNIT_TEST_SUITE_END();
 
+public:
+class Moveable {
+	int& moves;
+	int& copies;
+
+public:
+	Moveable(int& moves, int& copies) : moves(moves), copies(copies) {
+		moves = 0;
+		copies = 0;
+	}
+
+	Moveable(const Moveable& src) : moves(src.moves), copies(src.copies) {
+		copies++;
+	}
+
+	Moveable(Moveable&& src) : moves(src.moves), copies(src.copies) {
+		moves++;
+	}
+
+	bool operator<(const Moveable&) const {
+		return false;
+	}
+};
+
 public:
   void setUp();
   void tearDown();
diff --git a/alib2std/test-src/extensions/SharedPtrTest.cpp b/alib2std/test-src/extensions/SharedPtrTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6e30aaa5b3d053426ee0ff02e59f9a99356507da
--- /dev/null
+++ b/alib2std/test-src/extensions/SharedPtrTest.cpp
@@ -0,0 +1,42 @@
+#include "SharedPtrTest.h"
+#include <memory>
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( SharedPtrTest, "bits" );
+CPPUNIT_TEST_SUITE_REGISTRATION( SharedPtrTest );
+
+void SharedPtrTest::setUp() {
+}
+
+void SharedPtrTest::tearDown() {
+}
+
+void SharedPtrTest::testSharedPtr1() {
+	int moves;
+	int copies;
+
+	std::cow_shared_ptr<SharedPtrTest::Moveable> one(new SharedPtrTest::Moveable(moves, copies));
+
+	CPPUNIT_ASSERT(one.unique());
+	CPPUNIT_ASSERT(moves == 0);
+	CPPUNIT_ASSERT(copies == 0);
+
+	std::cow_shared_ptr<SharedPtrTest::Moveable> two(one);
+
+	CPPUNIT_ASSERT(!one.unique());
+	CPPUNIT_ASSERT(moves == 0);
+	CPPUNIT_ASSERT(copies == 0);
+
+	std::make_const(two).get();
+
+	CPPUNIT_ASSERT(!one.unique());
+	CPPUNIT_ASSERT(moves == 0);
+	CPPUNIT_ASSERT(copies == 0);
+
+	two.get();
+
+	CPPUNIT_ASSERT(one.unique());
+	CPPUNIT_ASSERT(moves == 0);
+	CPPUNIT_ASSERT(copies == 1);
+
+}
+
diff --git a/alib2std/test-src/extensions/SharedPtrTest.h b/alib2std/test-src/extensions/SharedPtrTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..9bf5bcb05ed0bfe5f3aaaa6195a2d4375b65b405
--- /dev/null
+++ b/alib2std/test-src/extensions/SharedPtrTest.h
@@ -0,0 +1,43 @@
+#ifndef TYPE_TRAITS_TEST_H_
+#define TYPE_TRAITS_TEST_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+
+class SharedPtrTest : public CppUnit::TestFixture
+{
+  CPPUNIT_TEST_SUITE( SharedPtrTest );
+  CPPUNIT_TEST( testSharedPtr1 );
+  CPPUNIT_TEST_SUITE_END();
+
+public:
+class Moveable {
+	int& moves;
+	int& copies;
+
+public:
+	Moveable(int& moves, int& copies) : moves(moves), copies(copies) {
+		moves = 0;
+		copies = 0;
+	}
+
+	Moveable(const Moveable& src) : moves(src.moves), copies(src.copies) {
+		copies++;
+	}
+
+	Moveable(Moveable&& src) : moves(src.moves), copies(src.copies) {
+		moves++;
+	}
+
+	bool operator<(const Moveable&) const {
+		return false;
+	}
+};
+
+public:
+  void setUp();
+  void tearDown();
+
+  void testSharedPtr1();
+};
+
+#endif  // TYPE_TRAITS_TEST_H_