- #include <iostream> 
- #include <utility> 
- #include <string> 
-   
- class Var 
- { 
- private: 
-     struct controlBlockBase 
-     { 
-         unsigned short uses; 
-   
-         controlBlockBase() : uses(1) { } 
-         virtual ~controlBlockBase() { } 
-     }; 
-   
-     template <class K> 
-     struct controlBlockImpl : controlBlockBase 
-     { 
-         K value; 
-         controlBlockImpl(const K &val) : controlBlockBase(), value(val) {} 
-     }; 
-   
-     controlBlockBase *cb; 
-   
- public: 
-     Var() : cb(nullptr) { 
-     	std::cout << "Var default constructed" << std::endl; 
-     } 
-   
-     template<typename K> 
-     Var(const K &value) : cb(new controlBlockImpl<K>(value)) {  
-     	std::cout << "Var value constructed" << std::endl; 
-     } 
-   
-     Var(const Var &obj) : cb(obj.cb) { 
-         if (cb) { 
-             ++(cb->uses); 
-         } 
-         std::cout << "Var copy constructed" << std::endl; 
-     } 
-   
-     Var(Var &&obj) : cb(nullptr) { 
-         obj.swap(*this); 
-         std::cout << "Var move constructed" << std::endl; 
-     } 
-   
-     ~Var() { 
-         if ((cb) && ((cb->uses -= 1) <= 0)) { 
-             delete cb; 
-             cb = nullptr; 
-         } 
-         std::cout << "Var destructed" << std::endl; 
-     } 
-   
-     Var& operator=(const Var& obj) { 
-         if (this != &obj) { 
-             Var(obj).swap(*this); 
-         } 
-         std::cout << "Var copy assigned" << std::endl; 
-         return *this; 
-     } 
-   
-     Var& operator=(Var &&obj) { 
-         obj.swap(*this); 
-         std::cout << "Var move assigned" << std::endl; 
-         return *this; 
-     } 
-   
-     void swap(Var &other) { 
-     	std::swap(cb, other.cb); 
-     } 
-   
-     unsigned short getUses() const { 
-     	return (cb) ? cb->uses : 0; 
-     } 
- }; 
-   
- namespace std { 
- 	void swap(Var &v1, Var &v2) { 
- 		v1.swap(v2); 
- 	} 
- } 
-   
- class C 
- { 
- public: 
-     Var var; 
-   
-     C() { 
-     	std::cout << "C default constructed" << std::endl; 
-     } 
-   
-     C(const C &c) : var(c.var) { 
-     	std::cout << "C copy constructed" << std::endl; 
-     } 
-   
-     C(C &&c) : var(std::move(c.var)) { 
-     	std::cout << "C move constructed" << std::endl; 
-     } 
-   
-     C(Var var) : var(var) { 
-     	std::cout << "C value constructed" << std::endl; 
-     } 
-   
-     ~C() { 
-     	std::cout << "C destructed" << std::endl; 
-     } 
-   
-     C& operator=(const C &c) { 
-     	if (this != &c) { 
-     		 C tmp(c); 
-     		 std::swap(var, tmp.var); 
-     	} 
-     	std::cout << "C copy assigned" << std::endl; 
-     	return *this; 
-     } 
-   
-     C& operator=(C &&c) { 
-         std::swap(var, c.var); 
-     	std::cout << "C move assigned" << std::endl; 
-     	return *this; 
-     } 
- }; 
-   
- class MyString 
- { 
- public: 
-     std::string str; 
-   
-     MyString() { 
-     	std::cout << "MyString default constructed" << std::endl; 
-     } 
-   
-     MyString(const char *s) : str(s) { 
-     	std::cout << "MyString value constructed" << std::endl; 
-     } 
-   
-     MyString(const std::string &s) : str(s) { 
-     	std::cout << "MyString value constructed" << std::endl; 
-     } 
-   
-     MyString(const MyString &s) : str(s.str) { 
-     	std::cout << "MyString copy constructed" << std::endl; 
-     } 
-   
-     MyString(MyString &&s) : str(std::move(s.str)) { 
-     	std::cout << "MyString move constructed" << std::endl; 
-     } 
-   
-     ~MyString() { 
-     	std::cout << "MyString destructed" << std::endl; 
-     } 
-   
-     MyString& operator=(const MyString &s) { 
-     	if (this != &s) { 
-     		 str = s.str; 
-     	} 
-     	std::cout << "MyString copy assigned" << std::endl; 
-     	return *this; 
-     } 
-   
-     MyString& operator=(MyString &&s) { 
-         str = std::move(s.str); 
-     	std::cout << "MyString move assigned" << std::endl; 
-     	return *this; 
-     } 
- }; 
-   
- void test() 
- { 
-     MyString string = "Hello"; 
-     Var var1 = Var(string); 
-     std::cout << "var1 uses=" << var1.getUses() << std::endl; 
-     C c = C(var1); 
-     std::cout << "var1 uses=" << var1.getUses() << std::endl; 
-     Var var2 = Var(c); 
-     std::cout << "var1 uses=" << var1.getUses() << std::endl; 
-     std::cout << "var2 uses=" << var2.getUses() << std::endl; 
- } 
-   
- int main() { 
-     test(); 
-     return 0; 
- }