Move models of smart pointers to custom namespace

Summary:
So far infer had very fragile mechanism to detect smart pointers. It was looking for "std" and "(shared|unique)_ptr" inside name string.
This is easy to trick (like mystd::shared_ptr) and not something we want.
Instead, inside models create models inside infer_std_model namespace. Then just "export" that model into std namespace
via `using shared_ptr = infer_std_model<T>;`

Reviewed By: jvillard

Differential Revision: D3703827

fbshipit-source-id: 9640fc2
master
Andrzej Kotulski 8 years ago committed by Facebook Github Bot 6
parent 49adf59332
commit 121c968e77

@ -12,65 +12,72 @@
#include <infer_model/common.h> #include <infer_model/common.h>
INFER_NAMESPACE_STD_BEGIN // define shared_ptr outside of std namespace. It will be aliased as
// std::shared_ptr via 'using' clause later
namespace infer_std_model {
// use inheritance to avoid compilation errors when using // use inheritance to avoid compilation errors when using
// methods / non-member functions that are not modeled // methods / non-member functions that are not modeled
// WARNING: sizeof(shared_ptr) = 24, not 16 - this may // WARNING: sizeof(shared_ptr) = 24, not 16 - this may
// lead to compilation errors // lead to compilation errors
template <class T> template <class T>
class shared_ptr : public std__shared_ptr<T> { class shared_ptr : public std::std__shared_ptr<T> {
public: public:
#if INFER_USE_LIBCPP #if INFER_USE_LIBCPP
using std__shared_ptr<T>::__ptr_; using std::std__shared_ptr<T>::__ptr_;
#define __data __ptr_ #define __data __ptr_
#else #else
using __shared_ptr<T>::_M_ptr; using std::__shared_ptr<T>::_M_ptr;
#define __data _M_ptr #define __data _M_ptr
#endif #endif
// Conversion constructors to allow implicit conversions. // Conversion constructors to allow implicit conversions.
// it's here purely to avoid compilation errors // it's here purely to avoid compilation errors
template <class Y, template <class Y,
typename = typename enable_if<is_convertible<Y*, T*>::value>::type> typename = typename std::enable_if<
shared_ptr(const std__shared_ptr<Y>& r) {} std::is_convertible<Y*, T*>::value>::type>
shared_ptr(const std::std__shared_ptr<Y>& r) {}
template <class Y> template <class Y>
shared_ptr(const std__shared_ptr<Y>& r, T* p) noexcept {} shared_ptr(const std::std__shared_ptr<Y>& r, T* p) noexcept {}
// constructors: // constructors:
constexpr shared_ptr() noexcept { __data = nullptr; } constexpr shared_ptr() noexcept { __data = nullptr; }
shared_ptr(nullptr_t) : shared_ptr() {} shared_ptr(std::nullptr_t) : shared_ptr() {}
// Extra template argument is used to create constructors/assignment overloads // Extra template argument is used to create constructors/assignment overloads
// for Y types where it's possible to convert Y* to T*. // for Y types where it's possible to convert Y* to T*.
// typename = typename enable_if<is_convertible<Y*, T*>::value>::type // typename = typename std::enable_if<std::is_convertible<Y*,
// T*>::value>::type
// thanks to that, clang will not create some functions that would cause // thanks to that, clang will not create some functions that would cause
// compilation errors. More info: // compilation errors. More info:
// http://en.cppreference.com/w/cpp/language/sfinae // http://en.cppreference.com/w/cpp/language/sfinae
template <class Y, template <class Y,
typename = typename enable_if<is_convertible<Y*, T*>::value>::type> typename = typename std::enable_if<
std::is_convertible<Y*, T*>::value>::type>
explicit shared_ptr(Y* p) { explicit shared_ptr(Y* p) {
__data = p; __data = p;
} }
template <class Y, template <class Y,
class D, class D,
typename = typename enable_if<is_convertible<Y*, T*>::value>::type> typename = typename std::enable_if<
std::is_convertible<Y*, T*>::value>::type>
shared_ptr(Y* p, D d) : shared_ptr<T>(p) {} shared_ptr(Y* p, D d) : shared_ptr<T>(p) {}
template <class Y, template <class Y,
class D, class D,
class A, class A,
typename = typename enable_if<is_convertible<Y*, T*>::value>::type> typename = typename std::enable_if<
std::is_convertible<Y*, T*>::value>::type>
shared_ptr(Y* p, D d, A a) : shared_ptr<T>(p) {} shared_ptr(Y* p, D d, A a) : shared_ptr<T>(p) {}
template <class D> template <class D>
shared_ptr(nullptr_t p, D d) : shared_ptr<T>(p) {} shared_ptr(std::nullptr_t p, D d) : shared_ptr<T>(p) {}
template <class D, class A> template <class D, class A>
shared_ptr(nullptr_t p, D d, A a) : shared_ptr<T>(p) {} shared_ptr(std::nullptr_t p, D d, A a) : shared_ptr<T>(p) {}
template <class Y> template <class Y>
shared_ptr(const shared_ptr<Y>& r, T* p) noexcept { shared_ptr(const shared_ptr<Y>& r, T* p) noexcept {
@ -82,7 +89,8 @@ class shared_ptr : public std__shared_ptr<T> {
} }
template <class Y, template <class Y,
typename = typename enable_if<is_convertible<Y*, T*>::value>::type> typename = typename std::enable_if<
std::is_convertible<Y*, T*>::value>::type>
shared_ptr(const shared_ptr<Y>& r) noexcept shared_ptr(const shared_ptr<Y>& r) noexcept
: shared_ptr<T>(r.__data) { /* TODO - increase refcount*/ : shared_ptr<T>(r.__data) { /* TODO - increase refcount*/
} }
@ -92,14 +100,16 @@ class shared_ptr : public std__shared_ptr<T> {
} }
template <class Y, template <class Y,
typename = typename enable_if<is_convertible<Y*, T*>::value>::type> typename = typename std::enable_if<
std::is_convertible<Y*, T*>::value>::type>
shared_ptr(shared_ptr<Y>&& r) noexcept : shared_ptr<T>(r.__data) { shared_ptr(shared_ptr<Y>&& r) noexcept : shared_ptr<T>(r.__data) {
r.__data = nullptr; r.__data = nullptr;
} }
template <class Y, template <class Y,
typename = typename enable_if<is_convertible<Y*, T*>::value>::type> typename = typename std::enable_if<
explicit shared_ptr(const weak_ptr<Y>& r) {} std::is_convertible<Y*, T*>::value>::type>
explicit shared_ptr(const std::weak_ptr<Y>& r) {}
/* Because of implementation differences between libc++ and stdlibc++, don't /* Because of implementation differences between libc++ and stdlibc++, don't
* define this constructor (it will be defined elsewhere in case of * define this constructor (it will be defined elsewhere in case of
@ -107,14 +117,15 @@ class shared_ptr : public std__shared_ptr<T> {
* converts to T* - otherwise there might be compilation error (out-of-line * converts to T* - otherwise there might be compilation error (out-of-line
* definition). * definition).
* No definition here might cause compilation problems if project is * No definition here might cause compilation problems if project is
* using auto_ptrs with libc++ */ * using std::auto_ptrs with libc++ */
template <class Y> template <class Y>
shared_ptr(auto_ptr<Y>&& r); // {} shared_ptr(std::auto_ptr<Y>&& r); // {}
template <class Y, template <class Y,
class D, class D,
typename = typename enable_if<is_convertible<Y*, T*>::value>::type> typename = typename std::enable_if<
shared_ptr(unique_ptr<Y, D>&& r) : shared_ptr<T>(r.release()) {} std::is_convertible<Y*, T*>::value>::type>
shared_ptr(std::unique_ptr<Y, D>&& r) : shared_ptr<T>(r.release()) {}
// destructor: // destructor:
~shared_ptr() { reset((T*)nullptr); } ~shared_ptr() { reset((T*)nullptr); }
@ -127,7 +138,8 @@ class shared_ptr : public std__shared_ptr<T> {
} }
template <class Y, template <class Y,
typename = typename enable_if<is_convertible<Y*, T*>::value>::type> typename = typename std::enable_if<
std::is_convertible<Y*, T*>::value>::type>
shared_ptr& operator=(const shared_ptr<Y>& r) noexcept { shared_ptr& operator=(const shared_ptr<Y>& r) noexcept {
// shared_ptr<T>(r).swap(*this); // shared_ptr<T>(r).swap(*this);
__data = r.__data; __data = r.__data;
@ -141,7 +153,8 @@ class shared_ptr : public std__shared_ptr<T> {
} }
template <class Y, template <class Y,
typename = typename enable_if<is_convertible<Y*, T*>::value>::type> typename = typename std::enable_if<
std::is_convertible<Y*, T*>::value>::type>
shared_ptr& operator=(shared_ptr<Y>&& r) { shared_ptr& operator=(shared_ptr<Y>&& r) {
// shared_ptr<T>(std::move(r)).swap(*this); // shared_ptr<T>(std::move(r)).swap(*this);
__data = r.__data; __data = r.__data;
@ -149,13 +162,15 @@ class shared_ptr : public std__shared_ptr<T> {
} }
template <class Y, template <class Y,
typename = typename enable_if<is_convertible<Y*, T*>::value>::type> typename = typename std::enable_if<
shared_ptr& operator=(auto_ptr<Y>&& r) { /* ?? */ std::is_convertible<Y*, T*>::value>::type>
shared_ptr& operator=(std::auto_ptr<Y>&& r) { /* ?? */
} }
template <class Y, template <class Y,
class D, class D,
typename = typename enable_if<is_convertible<Y*, T*>::value>::type> typename = typename std::enable_if<
shared_ptr& operator=(unique_ptr<Y, D>&& r) { std::is_convertible<Y*, T*>::value>::type>
shared_ptr& operator=(std::unique_ptr<Y, D>&& r) {
// shared_ptr<T>(std::move(r)).swap(*this); // shared_ptr<T>(std::move(r)).swap(*this);
return *this; return *this;
} }
@ -170,7 +185,8 @@ class shared_ptr : public std__shared_ptr<T> {
void reset() noexcept { reset((T*)nullptr); } void reset() noexcept { reset((T*)nullptr); }
template <class Y, template <class Y,
typename = typename enable_if<is_convertible<Y*, T*>::value>::type> typename = typename std::enable_if<
std::is_convertible<Y*, T*>::value>::type>
void reset(Y* p) { void reset(Y* p) {
/* /*
if (unique()) { if (unique()) {
@ -183,7 +199,8 @@ class shared_ptr : public std__shared_ptr<T> {
template <class Y, template <class Y,
class D, class D,
typename = typename enable_if<is_convertible<Y*, T*>::value>::type> typename = typename std::enable_if<
std::is_convertible<Y*, T*>::value>::type>
void reset(Y* p, D d) { void reset(Y* p, D d) {
reset(p); reset(p);
} }
@ -191,14 +208,15 @@ class shared_ptr : public std__shared_ptr<T> {
template <class Y, template <class Y,
class D, class D,
class A, class A,
typename = typename enable_if<is_convertible<Y*, T*>::value>::type> typename = typename std::enable_if<
std::is_convertible<Y*, T*>::value>::type>
void reset(Y* p, D d, A a) { void reset(Y* p, D d, A a) {
reset(p); reset(p);
} }
// observers: // observers:
T* get() const noexcept { return __data; } T* get() const noexcept { return __data; }
typename add_lvalue_reference<T>::type operator*() const noexcept { typename std::add_lvalue_reference<T>::type operator*() const noexcept {
return *__data; return *__data;
} }
T* operator->() const noexcept { return __data; } T* operator->() const noexcept { return __data; }
@ -210,10 +228,11 @@ class shared_ptr : public std__shared_ptr<T> {
return true; /* FIXME - use non-det*/ return true; /* FIXME - use non-det*/
} }
template <class U> template <class U>
bool owner_before(weak_ptr<U> const& b) const { bool owner_before(std::weak_ptr<U> const& b) const {
return true; /* FIXME - use non-det */ return true; /* FIXME - use non-det */
} }
}; };
template <class _Tp, class _Up> template <class _Tp, class _Up>
inline bool operator==(const shared_ptr<_Tp>& __x, inline bool operator==(const shared_ptr<_Tp>& __x,
const shared_ptr<_Up>& __y) noexcept { const shared_ptr<_Up>& __y) noexcept {
@ -229,8 +248,8 @@ inline bool operator!=(const shared_ptr<_Tp>& __x,
template <class _Tp, class _Up> template <class _Tp, class _Up>
inline bool operator<(const shared_ptr<_Tp>& __x, inline bool operator<(const shared_ptr<_Tp>& __x,
const shared_ptr<_Up>& __y) noexcept { const shared_ptr<_Up>& __y) noexcept {
typedef typename common_type<_Tp*, _Up*>::type _Vp; typedef typename std::common_type<_Tp*, _Up*>::type _Vp;
return less<_Vp>()(__x.get(), __y.get()); return std::less<_Vp>()(__x.get(), __y.get());
} }
template <class _Tp, class _Up> template <class _Tp, class _Up>
@ -252,64 +271,71 @@ inline bool operator>=(const shared_ptr<_Tp>& __x,
} }
template <class _Tp> template <class _Tp>
inline bool operator==(const shared_ptr<_Tp>& __x, nullptr_t) noexcept { inline bool operator==(const shared_ptr<_Tp>& __x, std::nullptr_t) noexcept {
return !__x; return !__x;
} }
template <class _Tp> template <class _Tp>
inline bool operator==(nullptr_t, const shared_ptr<_Tp>& __x) noexcept { inline bool operator==(std::nullptr_t, const shared_ptr<_Tp>& __x) noexcept {
return !__x; return !__x;
} }
template <class _Tp> template <class _Tp>
inline bool operator!=(const shared_ptr<_Tp>& __x, nullptr_t) noexcept { inline bool operator!=(const shared_ptr<_Tp>& __x, std::nullptr_t) noexcept {
return static_cast<bool>(__x); return static_cast<bool>(__x);
} }
template <class _Tp> template <class _Tp>
inline bool operator!=(nullptr_t, const shared_ptr<_Tp>& __x) noexcept { inline bool operator!=(std::nullptr_t, const shared_ptr<_Tp>& __x) noexcept {
return static_cast<bool>(__x); return static_cast<bool>(__x);
} }
template <class _Tp> template <class _Tp>
inline bool operator<(const shared_ptr<_Tp>& __x, nullptr_t) noexcept { inline bool operator<(const shared_ptr<_Tp>& __x, std::nullptr_t) noexcept {
return less<_Tp*>()(__x.get(), nullptr); return std::less<_Tp*>()(__x.get(), nullptr);
} }
template <class _Tp> template <class _Tp>
inline bool operator<(nullptr_t, const shared_ptr<_Tp>& __x) noexcept { inline bool operator<(std::nullptr_t, const shared_ptr<_Tp>& __x) noexcept {
return less<_Tp*>()(nullptr, __x.get()); return std::less<_Tp*>()(nullptr, __x.get());
} }
template <class _Tp> template <class _Tp>
inline bool operator>(const shared_ptr<_Tp>& __x, nullptr_t) noexcept { inline bool operator>(const shared_ptr<_Tp>& __x, std::nullptr_t) noexcept {
return nullptr < __x; return nullptr < __x;
} }
template <class _Tp> template <class _Tp>
inline bool operator>(nullptr_t, const shared_ptr<_Tp>& __x) noexcept { inline bool operator>(std::nullptr_t, const shared_ptr<_Tp>& __x) noexcept {
return __x < nullptr; return __x < nullptr;
} }
template <class _Tp> template <class _Tp>
inline bool operator<=(const shared_ptr<_Tp>& __x, nullptr_t) noexcept { inline bool operator<=(const shared_ptr<_Tp>& __x, std::nullptr_t) noexcept {
return !(nullptr < __x); return !(nullptr < __x);
} }
template <class _Tp> template <class _Tp>
inline bool operator<=(nullptr_t, const shared_ptr<_Tp>& __x) noexcept { inline bool operator<=(std::nullptr_t, const shared_ptr<_Tp>& __x) noexcept {
return !(__x < nullptr); return !(__x < nullptr);
} }
template <class _Tp> template <class _Tp>
inline bool operator>=(const shared_ptr<_Tp>& __x, nullptr_t) noexcept { inline bool operator>=(const shared_ptr<_Tp>& __x, std::nullptr_t) noexcept {
return !(__x < nullptr); return !(__x < nullptr);
} }
template <class _Tp> template <class _Tp>
inline bool operator>=(nullptr_t, const shared_ptr<_Tp>& __x) noexcept { inline bool operator>=(std::nullptr_t, const shared_ptr<_Tp>& __x) noexcept {
return !(nullptr < __x); return !(nullptr < __x);
} }
} // namespace infer_std_model
INFER_NAMESPACE_STD_BEGIN
// make std::shared_ptr alias of infer_std_model::shared_ptr
template <class T>
using shared_ptr = infer_std_model::shared_ptr<T>;
template <class T> template <class T>
struct hash<shared_ptr<T>> : public hash<std__shared_ptr<T>> {}; struct hash<shared_ptr<T>> : public hash<std__shared_ptr<T>> {};

@ -11,12 +11,14 @@
#include <infer_model/common.h> #include <infer_model/common.h>
INFER_NAMESPACE_STD_BEGIN // define unique_ptr outside of std namespace. It will be aliased as
// std::unique_ptr via 'using' clause later
namespace infer_std_model {
// IMPORTANT // IMPORTANT
// There is specialization of unique_ptr below and it's mosly copy paste. // There is specialization of unique_ptr below and it's mosly copy paste.
// When changing model, remember to change it for specialization as well! // When changing model, remember to change it for specialization as well!
template <class _Tp, class _Dp = default_delete<_Tp>> template <class _Tp, class _Dp>
struct unique_ptr { struct unique_ptr {
// use SFINAE to determine whether _Del::pointer exists // use SFINAE to determine whether _Del::pointer exists
class _Pointer { class _Pointer {
@ -26,7 +28,7 @@ struct unique_ptr {
template <typename _Up> template <typename _Up>
static _Tp* __test(...); static _Tp* __test(...);
typedef typename remove_reference<_Dp>::type _Del; typedef typename std::remove_reference<_Dp>::type _Del;
public: public:
typedef decltype(__test<_Del>(0)) type; typedef decltype(__test<_Del>(0)) type;
@ -39,44 +41,45 @@ struct unique_ptr {
pointer data; pointer data;
template <class Y> template <class Y>
unique_ptr(const std__unique_ptr<Y>& u) {} unique_ptr(const std::std__unique_ptr<Y>& u) {}
constexpr unique_ptr() noexcept : data(nullptr) {} constexpr unique_ptr() noexcept : data(nullptr) {}
constexpr unique_ptr(nullptr_t) noexcept : unique_ptr<_Tp, _Dp>() {} constexpr unique_ptr(std::nullptr_t) noexcept : unique_ptr<_Tp, _Dp>() {}
explicit unique_ptr(pointer ptr) : data(ptr) {} explicit unique_ptr(pointer ptr) : data(ptr) {}
unique_ptr(pointer ptr, unique_ptr(pointer ptr,
typename conditional< typename std::conditional<
is_reference<deleter_type>::value, std::is_reference<deleter_type>::value,
deleter_type, deleter_type,
typename add_lvalue_reference<const deleter_type>::type>::type typename std::add_lvalue_reference<const deleter_type>::type>::type
__d) noexcept : data(ptr) {} __d) noexcept : data(ptr) {}
unique_ptr(pointer ptr, unique_ptr(pointer ptr,
typename remove_reference<deleter_type>::type&& __d) noexcept typename std::remove_reference<deleter_type>::type&& __d) noexcept
: data(ptr) {} : data(ptr) {}
unique_ptr(unique_ptr&& u) noexcept : data(u.data) { u.data = nullptr; } unique_ptr(unique_ptr&& u) noexcept : data(u.data) { u.data = nullptr; }
template <class _Up, template <class _Up,
class _Ep, class _Ep,
typename = typename enable_if< typename = typename std::enable_if<
!is_array<_Up>::value && !std::is_array<_Up>::value &&
is_convertible<typename unique_ptr<_Up, _Ep>::pointer, std::is_convertible<typename unique_ptr<_Up, _Ep>::pointer,
pointer>::value && pointer>::value &&
is_convertible<_Ep, deleter_type>::value && std::is_convertible<_Ep, deleter_type>::value &&
(!is_reference<deleter_type>::value || (!std::is_reference<deleter_type>::value ||
is_same<deleter_type, _Ep>::value)>::type> std::is_same<deleter_type, _Ep>::value)>::type>
unique_ptr(unique_ptr<_Up, _Ep>&& u) noexcept : data(u.data) { unique_ptr(unique_ptr<_Up, _Ep>&& u) noexcept : data(u.data) {
u.data = nullptr; u.data = nullptr;
} }
template < template <
class _Up, class _Up,
typename = typename enable_if<is_convertible<_Up*, _Tp*>::value>::type> typename = typename std::enable_if<
unique_ptr(auto_ptr<_Up>&& __p) noexcept; std::is_convertible<_Up*, _Tp*>::value>::type>
unique_ptr(std::auto_ptr<_Up>&& __p) noexcept;
~unique_ptr() { reset(); } ~unique_ptr() { reset(); }
@ -87,28 +90,30 @@ struct unique_ptr {
template <class _Up, template <class _Up,
class _Ep, class _Ep,
typename = typename enable_if< typename = typename std::enable_if<
!is_array<_Up>::value && !std::is_array<_Up>::value &&
is_convertible<typename unique_ptr<_Up, _Ep>::pointer, std::is_convertible<typename unique_ptr<_Up, _Ep>::pointer,
pointer>::value && pointer>::value &&
is_assignable<deleter_type&, _Ep&&>::value>::type> std::is_assignable<deleter_type&, _Ep&&>::value>::type>
unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) noexcept { unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) noexcept {
reset(__u.data); reset(__u.data);
return *this; return *this;
} }
unique_ptr& operator=(nullptr_t) noexcept { unique_ptr& operator=(std::nullptr_t) noexcept {
reset(); reset();
return *this; return *this;
} }
typename add_lvalue_reference<_Tp>::type operator*() const { return *data; } typename std::add_lvalue_reference<_Tp>::type operator*() const {
return *data;
}
pointer operator->() const { return data; } pointer operator->() const { return data; }
pointer get() const { return data; } pointer get() const { return data; }
typedef typename remove_reference<deleter_type>::type& _Dp_reference; typedef typename std::remove_reference<deleter_type>::type& _Dp_reference;
typedef const typename remove_reference<deleter_type>::type& typedef const typename std::remove_reference<deleter_type>::type&
_Dp_const_reference; _Dp_const_reference;
_Dp_const_reference get_deleter() const {} _Dp_const_reference get_deleter() const {}
_Dp_reference get_deleter() {} _Dp_reference get_deleter() {}
@ -135,7 +140,7 @@ struct unique_ptr<_Tp[], _Dp> {
template <typename _Up> template <typename _Up>
static _Tp* __test(...); static _Tp* __test(...);
typedef typename remove_reference<_Dp>::type _Del; typedef typename std::remove_reference<_Dp>::type _Del;
public: public:
typedef decltype(__test<_Del>(0)) type; typedef decltype(__test<_Del>(0)) type;
@ -150,40 +155,42 @@ struct unique_ptr<_Tp[], _Dp> {
constexpr unique_ptr() noexcept : data(nullptr) {} constexpr unique_ptr() noexcept : data(nullptr) {}
constexpr unique_ptr(nullptr_t) noexcept : data(nullptr) {} constexpr unique_ptr(std::nullptr_t) noexcept : data(nullptr) {}
explicit unique_ptr(pointer ptr) : data(ptr) {} explicit unique_ptr(pointer ptr) : data(ptr) {}
unique_ptr( unique_ptr(
pointer ptr, pointer ptr,
typename conditional< typename std::conditional<std::is_reference<deleter_type>::value,
is_reference<deleter_type>::value, deleter_type,
deleter_type, typename std::add_lvalue_reference<
typename add_lvalue_reference<const deleter_type>::type>::type __d) const deleter_type>::type>::type __d)
: data(ptr) {} : data(ptr) {}
unique_ptr(pointer ptr, typename remove_reference<deleter_type>::type&& __d) unique_ptr(pointer ptr,
typename std::remove_reference<deleter_type>::type&& __d)
: data(ptr) {} : data(ptr) {}
unique_ptr(unique_ptr&& u) : data(u.data) { u.data = nullptr; } unique_ptr(unique_ptr&& u) : data(u.data) { u.data = nullptr; }
template <class _Up, template <class _Up,
class _Ep, class _Ep,
typename = typename enable_if< typename = typename std::enable_if<
is_array<_Up>::value && std::is_array<_Up>::value &&
is_convertible<typename unique_ptr<_Up, _Ep>::pointer, std::is_convertible<typename unique_ptr<_Up, _Ep>::pointer,
pointer>::value && pointer>::value &&
is_convertible<_Ep, deleter_type>::value && std::is_convertible<_Ep, deleter_type>::value &&
(!is_reference<deleter_type>::value || (!std::is_reference<deleter_type>::value ||
is_same<deleter_type, _Ep>::value)>::type> std::is_same<deleter_type, _Ep>::value)>::type>
unique_ptr(unique_ptr<_Up, _Ep>&& u) : data(u.data) { unique_ptr(unique_ptr<_Up, _Ep>&& u) : data(u.data) {
u.data = nullptr; u.data = nullptr;
} }
template < template <
class _Up, class _Up,
typename = typename enable_if<is_convertible<_Up*, _Tp*>::value>::type> typename = typename std::enable_if<
unique_ptr(auto_ptr<_Up>&& __p) noexcept; std::is_convertible<_Up*, _Tp*>::value>::type>
unique_ptr(std::auto_ptr<_Up>&& __p) noexcept;
~unique_ptr() { reset(); } ~unique_ptr() { reset(); }
@ -194,27 +201,27 @@ struct unique_ptr<_Tp[], _Dp> {
template <class _Up, template <class _Up,
class _Ep, class _Ep,
typename = typename enable_if< typename = typename std::enable_if<
is_array<_Up>::value && std::is_array<_Up>::value &&
is_convertible<typename unique_ptr<_Up, _Ep>::pointer, std::is_convertible<typename unique_ptr<_Up, _Ep>::pointer,
pointer>::value && pointer>::value &&
is_assignable<deleter_type&, _Ep&&>::value>::type> std::is_assignable<deleter_type&, _Ep&&>::value>::type>
unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) { unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) {
reset(__u.data); reset(__u.data);
return *this; return *this;
} }
unique_ptr& operator=(nullptr_t) { unique_ptr& operator=(std::nullptr_t) {
reset(); reset();
return *this; return *this;
} }
typename add_lvalue_reference<_Tp>::type operator[](size_t i) const {} typename std::add_lvalue_reference<_Tp>::type operator[](size_t i) const {}
pointer get() const { return data; } pointer get() const { return data; }
typedef typename remove_reference<deleter_type>::type& _Dp_reference; typedef typename std::remove_reference<deleter_type>::type& _Dp_reference;
typedef const typename remove_reference<deleter_type>::type& typedef const typename std::remove_reference<deleter_type>::type&
_Dp_const_reference; _Dp_const_reference;
_Dp_const_reference get_deleter() const {} _Dp_const_reference get_deleter() const {}
_Dp_reference get_deleter() {} _Dp_reference get_deleter() {}
@ -271,66 +278,74 @@ inline bool operator>=(const unique_ptr<_T1, _D1>& __x,
} }
template <class _T1, class _D1> template <class _T1, class _D1>
inline bool operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) { inline bool operator==(const unique_ptr<_T1, _D1>& __x, std::nullptr_t) {
return !__x; return !__x;
} }
template <class _T1, class _D1> template <class _T1, class _D1>
inline bool operator==(nullptr_t, const unique_ptr<_T1, _D1>& __x) { inline bool operator==(std::nullptr_t, const unique_ptr<_T1, _D1>& __x) {
return !__x; return !__x;
} }
template <class _T1, class _D1> template <class _T1, class _D1>
inline bool operator!=(const unique_ptr<_T1, _D1>& __x, nullptr_t) { inline bool operator!=(const unique_ptr<_T1, _D1>& __x, std::nullptr_t) {
return static_cast<bool>(__x); return static_cast<bool>(__x);
} }
template <class _T1, class _D1> template <class _T1, class _D1>
inline bool operator!=(nullptr_t, const unique_ptr<_T1, _D1>& __x) { inline bool operator!=(std::nullptr_t, const unique_ptr<_T1, _D1>& __x) {
return static_cast<bool>(__x); return static_cast<bool>(__x);
} }
template <class _T1, class _D1> template <class _T1, class _D1>
inline bool operator<(const unique_ptr<_T1, _D1>& __x, nullptr_t) { inline bool operator<(const unique_ptr<_T1, _D1>& __x, std::nullptr_t) {
/*typedef typename unique_ptr<_T1, _D1>::pointer _P1; /*typedef typename unique_ptr<_T1, _D1>::pointer _P1;
return less<_P1>()(__x.get(), nullptr);*/ return less<_P1>()(__x.get(), nullptr);*/
} }
template <class _T1, class _D1> template <class _T1, class _D1>
inline bool operator<(nullptr_t, const unique_ptr<_T1, _D1>& __x) { inline bool operator<(std::nullptr_t, const unique_ptr<_T1, _D1>& __x) {
/*typedef typename unique_ptr<_T1, _D1>::pointer _P1; /*typedef typename unique_ptr<_T1, _D1>::pointer _P1;
return less<_P1>()(nullptr, __x.get());*/ return less<_P1>()(nullptr, __x.get());*/
} }
template <class _T1, class _D1> template <class _T1, class _D1>
inline bool operator>(const unique_ptr<_T1, _D1>& __x, nullptr_t) { inline bool operator>(const unique_ptr<_T1, _D1>& __x, std::nullptr_t) {
return nullptr < __x; return nullptr < __x;
} }
template <class _T1, class _D1> template <class _T1, class _D1>
inline bool operator>(nullptr_t, const unique_ptr<_T1, _D1>& __x) { inline bool operator>(std::nullptr_t, const unique_ptr<_T1, _D1>& __x) {
return __x < nullptr; return __x < nullptr;
} }
template <class _T1, class _D1> template <class _T1, class _D1>
inline bool operator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t) { inline bool operator<=(const unique_ptr<_T1, _D1>& __x, std::nullptr_t) {
return !(nullptr < __x); return !(nullptr < __x);
} }
template <class _T1, class _D1> template <class _T1, class _D1>
inline bool operator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x) { inline bool operator<=(std::nullptr_t, const unique_ptr<_T1, _D1>& __x) {
return !(__x < nullptr); return !(__x < nullptr);
} }
template <class _T1, class _D1> template <class _T1, class _D1>
inline bool operator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t) { inline bool operator>=(const unique_ptr<_T1, _D1>& __x, std::nullptr_t) {
return !(__x < nullptr); return !(__x < nullptr);
} }
template <class _T1, class _D1> template <class _T1, class _D1>
inline bool operator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x) { inline bool operator>=(std::nullptr_t, const unique_ptr<_T1, _D1>& __x) {
return !(nullptr < __x); return !(nullptr < __x);
} }
} // namespace infer_std_model
INFER_NAMESPACE_STD_BEGIN
// make std::unique_ptr alias of infer_std_model::unique_ptr
template <class _Tp, class _Dp = default_delete<_Tp>>
using unique_ptr = infer_std_model::unique_ptr<_Tp, _Dp>;
template <class T, class D> template <class T, class D>
struct hash<unique_ptr<T, D>> : public hash<std__unique_ptr<T, D>> { struct hash<unique_ptr<T, D>> : public hash<std__unique_ptr<T, D>> {

@ -17,8 +17,8 @@ module F = Format
module DExp = DecompiledExp module DExp = DecompiledExp
let smart_pointers = [ let smart_pointers = [
["std"; "shared_ptr"]; ["infer_std_model"; "shared_ptr"];
["std"; "unique_ptr"] ["infer_std_model"; "unique_ptr"]
] ]
let pointer_wrapper_classes = smart_pointers let pointer_wrapper_classes = smart_pointers

Loading…
Cancel
Save