| /** | |
| * 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*; | |
| } |