mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	
		
			
				
	
	
		
			168 lines
		
	
	
	
		
			4.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			168 lines
		
	
	
	
		
			4.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // clonable_ptr: a smart pointer with a usage similar to unique_ptr, with the exception, that
 | |
| // the copy constructor / copy assignment operator work by calling the ->clone() method.
 | |
| 
 | |
| // derived from https://github.com/SRombauts/shared_ptr/blob/master/include/unique_ptr.hpp
 | |
| /**
 | |
|  * @file  clonable_ptr.hpp
 | |
|  * @brief clonable_ptr is a fake implementation to use in place of a C++11 std::clonable_ptr when compiling on an older compiler.
 | |
|  *
 | |
|  * @see http://www.cplusplus.com/reference/memory/clonable_ptr/
 | |
|  *
 | |
|  * Copyright (c) 2014-2019 Sebastien Rombauts (sebastien.rombauts@gmail.com)
 | |
|  *
 | |
|  * Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
 | |
|  * or copy at http://opensource.org/licenses/MIT)
 | |
|  */
 | |
| 
 | |
| #include "assert.h"
 | |
| 
 | |
| namespace Slic3r {
 | |
| 
 | |
| // Detect whether the compiler supports C++11 noexcept exception specifications.
 | |
| #if defined(_MSC_VER) && _MSC_VER < 1900 && ! defined(noexcept)
 | |
|     #define noexcept throw()
 | |
| #endif
 | |
| 
 | |
| template<class T>
 | |
| class clonable_ptr
 | |
| {
 | |
| public:
 | |
|     /// The type of the managed object, aliased as member type
 | |
|     typedef T element_type;
 | |
| 
 | |
|     /// @brief Default constructor
 | |
|     clonable_ptr() noexcept :
 | |
|         px(nullptr)
 | |
|     {
 | |
|     }
 | |
|     /// @brief Constructor with the provided pointer to manage
 | |
|     explicit clonable_ptr(T* p) noexcept :
 | |
|         px(p)
 | |
|     {
 | |
|     }
 | |
|     /// @brief Copy constructor, clones by calling the rhs.clone() method
 | |
|     clonable_ptr(const clonable_ptr& rhs) :
 | |
| 		px(rhs ? rhs.px->clone() : nullptr)
 | |
|     {
 | |
|     }
 | |
|     /// @brief Move constructor, never throws
 | |
|     clonable_ptr(clonable_ptr&& rhs) noexcept :
 | |
|         px(rhs.px)
 | |
|     {
 | |
|         rhs.px = nullptr;
 | |
|     }
 | |
|     /// @brief Assignment operator
 | |
|     clonable_ptr& operator=(const clonable_ptr& rhs)
 | |
|     {
 | |
| 		delete px;
 | |
| 		px = rhs ? rhs.px->clone() : nullptr;
 | |
|         return *this;
 | |
|     }
 | |
|     /// @brief Move operator, never throws
 | |
|     clonable_ptr& operator=(clonable_ptr&& rhs)
 | |
|     {
 | |
| 		delete px;
 | |
|         px = rhs.px;
 | |
|         rhs.px = nullptr;
 | |
|         return *this;
 | |
|     }
 | |
|     /// @brief the destructor releases its ownership and destroy the object
 | |
|     inline ~clonable_ptr() noexcept
 | |
|     {
 | |
|         destroy();
 | |
|     }
 | |
|     /// @brief this reset releases its ownership and destroy the object
 | |
|     inline void reset() noexcept
 | |
|     {
 | |
|         destroy();
 | |
|     }
 | |
|     /// @brief this reset release its ownership and re-acquire another one
 | |
|     void reset(T* p) noexcept
 | |
|     {
 | |
|         assert((nullptr == p) || (px != p)); // auto-reset not allowed
 | |
|         destroy();
 | |
|         px = p;
 | |
|     }
 | |
| 
 | |
|     /// @brief Swap method for the copy-and-swap idiom (copy constructor and swap method)
 | |
|     void swap(clonable_ptr& rhs) noexcept
 | |
|     {
 | |
|         T *tmp = px;
 | |
|         px = rhs.px;
 | |
|         rhs.px = tmp;
 | |
|     }
 | |
| 
 | |
|     /// @brief release the ownership of the px pointer without destroying the object!
 | |
|     inline void release() noexcept
 | |
|     {
 | |
|         px = nullptr;
 | |
|     }
 | |
| 
 | |
|     // reference counter operations :
 | |
|     inline operator bool() const noexcept
 | |
|     {
 | |
|         return (nullptr != px); // TODO nullptrptr
 | |
|     }
 | |
| 
 | |
|     // underlying pointer operations :
 | |
|     inline T& operator*()  const noexcept
 | |
|     {
 | |
|         assert(nullptr != px);
 | |
|         return *px;
 | |
|     }
 | |
|     inline T* operator->() const noexcept
 | |
|     {
 | |
|         assert(nullptr != px);
 | |
|         return px;
 | |
|     }
 | |
|     inline T* get()  const noexcept
 | |
|     {
 | |
|         // no assert, can return nullptr
 | |
|         return px;
 | |
|     }
 | |
| 
 | |
| private:
 | |
|     /// @brief release the ownership of the px pointer and destroy the object
 | |
|     inline void destroy() noexcept
 | |
|     {
 | |
|         delete px;
 | |
|         px = nullptr;
 | |
|     }
 | |
| 
 | |
|     /// @brief hack: const-cast release the ownership of the px pointer without destroying the object!
 | |
|     inline void release() const noexcept
 | |
|     {
 | |
|         px = nullptr;
 | |
|     }
 | |
| 
 | |
| private:
 | |
|     T* px; //!< Native pointer
 | |
| };
 | |
| 
 | |
| // comparison operators
 | |
| template<class T, class U> inline bool operator==(const clonable_ptr<T>& l, const clonable_ptr<U>& r) noexcept
 | |
| {
 | |
|     return (l.get() == r.get());
 | |
| }
 | |
| template<class T, class U> inline bool operator!=(const clonable_ptr<T>& l, const clonable_ptr<U>& r) noexcept
 | |
| {
 | |
|     return (l.get() != r.get());
 | |
| }
 | |
| template<class T, class U> inline bool operator<=(const clonable_ptr<T>& l, const clonable_ptr<U>& r) noexcept
 | |
| {
 | |
|     return (l.get() <= r.get());
 | |
| }
 | |
| template<class T, class U> inline bool operator<(const clonable_ptr<T>& l, const clonable_ptr<U>& r) noexcept
 | |
| {
 | |
|     return (l.get() < r.get());
 | |
| }
 | |
| template<class T, class U> inline bool operator>=(const clonable_ptr<T>& l, const clonable_ptr<U>& r) noexcept
 | |
| {
 | |
|     return (l.get() >= r.get());
 | |
| }
 | |
| template<class T, class U> inline bool operator>(const clonable_ptr<T>& l, const clonable_ptr<U>& r) noexcept
 | |
| {
 | |
|     return (l.get() > r.get());
 | |
| }
 | |
| 
 | |
| } // namespace Slic3r
 | 
