/*** D binding to C++ <memory>.** Copyright: Copyright (c) 2019 D Language Foundation* License: Distributed under the* $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).* (See accompanying file LICENSE)* Authors: Manu Evans* Source: $(DRUNTIMESRC core/stdcpp/memory.d)*/ module core.stdcpp.memory; public import core.stdcpp.allocator; import core.stdcpp.xutility : StdNamespace; extern(C++, (StdNamespace)): ///unique_ptr!T make_unique(T, Args...)(auto ref Args args){ import core.lifetime : forward; import core.stdcpp.new_ : cpp_new; return unique_ptr!T(cpp_new!T(forward!args));} ///struct default_delete(T){ /// alias pointer = ClassOrPtr!T; /// void opCall()(pointer ptr) const { import core.stdcpp.new_ : cpp_delete; cpp_delete(ptr); }} ///extern(C++, class)struct unique_ptr(T, Deleter = default_delete!T){extern(D): /// this(this) @disable; /// ~this() { reset(); } /// ref unique_ptr opAssign(typeof(null)) { reset(); return this; } /// void reset(pointer p = null) { pointer t = __ptr(); __ptr() = p; if (t) get_deleter()(t); } nothrow pure @safe @nogc: /// alias pointer = ClassOrPtr!T; /// alias element_type = T; /// alias deleter_type = Deleter; /// this(pointer ptr) { __ptr() = ptr; } /// inout(pointer) get() inout nothrow { return __ptr(); } /// bool opCast(T : bool)() const nothrow { return __ptr() != null; } /// pointer release() nothrow { pointer t = __ptr(); __ptr() = null; return t; } // void swap(ref unique_ptr u) nothrow// {// __ptr_.swap(__u.__ptr_);// } version (CppRuntime_Microsoft) { /// ref inout(deleter_type) get_deleter() inout nothrow { return _Mypair._Myval1; } private: import core.stdcpp.xutility : _Compressed_pair; ref pointer __ptr() nothrow { return _Mypair._Myval2; } inout(pointer) __ptr() inout nothrow { return _Mypair._Myval2; } _Compressed_pair!(Deleter, pointer) _Mypair; } else version (CppRuntime_GNU) { /// ref inout(deleter_type) get_deleter() inout nothrow { return _M_t.get!1; } private: import core.stdcpp.tuple : tuple, get; ref pointer __ptr() nothrow { return _M_t.get!0; } inout(pointer) __ptr() inout nothrow { return _M_t.get!0; } tuple!(pointer, Deleter) _M_t; } else version (CppRuntime_LLVM) { /// ref inout(deleter_type) get_deleter() inout nothrow { return __ptr_.second; } private: import core.stdcpp.xutility : __compressed_pair; ref pointer __ptr() nothrow { return __ptr_.first; } inout(pointer) __ptr() inout nothrow { return __ptr_.first; } __compressed_pair!(pointer, deleter_type) __ptr_; }} private: template ClassOrPtr(T){ static if (is(T == class)) alias ClassOrPtr = T; else alias ClassOrPtr = T*;}
/**
* D binding to C++ <memory>.
*
* Copyright: Copyright (c) 2019 D Language Foundation
* License: Distributed under the
* $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
* (See accompanying file LICENSE)
* Authors: Manu Evans
* Source: $(DRUNTIMESRC core/stdcpp/memory.d)
*/
module core.stdcpp.memory;
public import core.stdcpp.allocator;
import core.stdcpp.xutility : StdNamespace;
extern(C++, (StdNamespace)):
///
unique_ptr!T make_unique(T, Args...)(auto ref Args args)
{
import core.lifetime : forward;
import core.stdcpp.new_ : cpp_new;
return unique_ptr!T(cpp_new!T(forward!args));
}
///
struct default_delete(T)
{
///
alias pointer = ClassOrPtr!T;
///
void opCall()(pointer ptr) const
{
import core.stdcpp.new_ : cpp_delete;
cpp_delete(ptr);
}
}
///
extern(C++, class)
struct unique_ptr(T, Deleter = default_delete!T)
{
extern(D):
///
this(this) @disable;
///
~this()
{
reset();
}
///
ref unique_ptr opAssign(typeof(null))
{
reset();
return this;
}
///
void reset(pointer p = null)
{
pointer t = __ptr();
__ptr() = p;
if (t)
get_deleter()(t);
}
nothrow pure @safe @nogc:
///
alias pointer = ClassOrPtr!T;
///
alias element_type = T;
///
alias deleter_type = Deleter;
///
this(pointer ptr)
{
__ptr() = ptr;
}
///
inout(pointer) get() inout nothrow
{
return __ptr();
}
///
bool opCast(T : bool)() const nothrow
{
return __ptr() != null;
}
///
pointer release() nothrow
{
pointer t = __ptr();
__ptr() = null;
return t;
}
// void swap(ref unique_ptr u) nothrow
// {
// __ptr_.swap(__u.__ptr_);
// }
version (CppRuntime_Microsoft)
{
///
ref inout(deleter_type) get_deleter() inout nothrow { return _Mypair._Myval1; }
private:
import core.stdcpp.xutility : _Compressed_pair;
ref pointer __ptr() nothrow { return _Mypair._Myval2; }
inout(pointer) __ptr() inout nothrow { return _Mypair._Myval2; }
_Compressed_pair!(Deleter, pointer) _Mypair;
}
else version (CppRuntime_GNU)
{
///
ref inout(deleter_type) get_deleter() inout nothrow { return _M_t.get!1; }
private:
import core.stdcpp.tuple : tuple, get;
ref pointer __ptr() nothrow { return _M_t.get!0; }
inout(pointer) __ptr() inout nothrow { return _M_t.get!0; }
tuple!(pointer, Deleter) _M_t;
}
else version (CppRuntime_LLVM)
{
///
ref inout(deleter_type) get_deleter() inout nothrow { return __ptr_.second; }
private:
import core.stdcpp.xutility : __compressed_pair;
ref pointer __ptr() nothrow { return __ptr_.first; }
inout(pointer) __ptr() inout nothrow { return __ptr_.first; }
__compressed_pair!(pointer, deleter_type) __ptr_;
}
}
private:
template ClassOrPtr(T)
{
static if (is(T == class))
alias ClassOrPtr = T;
else
alias ClassOrPtr = T*;
}