This repository has been archived by the owner on Oct 12, 2022. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 421
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2286 from TurkeyMan/std_array
Added std::array<>
- Loading branch information
Showing
15 changed files
with
356 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
Added `core.stdcpp.array`. | ||
|
||
Added `core.stdcpp.array`, which links against C++ `std::array` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
/** | ||
* D header file for interaction with C++ std::array. | ||
* | ||
* Copyright: Copyright (c) 2018 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/array.d) | ||
*/ | ||
|
||
module core.stdcpp.array; | ||
|
||
// hacks to support DMD on Win32 | ||
version (CppRuntime_Microsoft) | ||
{ | ||
version = CppRuntime_Windows; // use the MS runtime ABI for win32 | ||
} | ||
else version (CppRuntime_DigitalMars) | ||
{ | ||
version = CppRuntime_Windows; // use the MS runtime ABI for win32 | ||
pragma(msg, "std::array not supported by DMC"); | ||
} | ||
version (CppRuntime_Clang) | ||
{ | ||
private alias AliasSeq(Args...) = Args; | ||
private enum StdNamespace = AliasSeq!("std", "__1"); | ||
} | ||
else | ||
{ | ||
private enum StdNamespace = "std"; | ||
} | ||
|
||
extern(C++, (StdNamespace)): | ||
|
||
/** | ||
* D language counterpart to C++ std::array. | ||
* | ||
* C++ reference: $(LINK2 https://en.cppreference.com/w/cpp/container/array) | ||
*/ | ||
extern(C++, class) struct array(T, size_t N) | ||
{ | ||
extern(D): | ||
pragma(inline, true): | ||
|
||
/// | ||
alias size_type = size_t; | ||
/// | ||
alias difference_type = ptrdiff_t; | ||
/// | ||
alias value_type = T; | ||
/// | ||
alias pointer = T*; | ||
/// | ||
alias const_pointer = const(T)*; | ||
|
||
/// | ||
alias as_array this; | ||
|
||
/// Variadic constructor | ||
this(T[N] args ...) { this[] = args[]; } | ||
|
||
/// | ||
size_type size() const nothrow @safe @nogc { return N; } | ||
/// | ||
alias length = size; | ||
/// | ||
alias opDollar = length; | ||
/// | ||
size_type max_size() const nothrow @safe @nogc { return N; } | ||
/// | ||
bool empty() const nothrow @safe @nogc { return N == 0; } | ||
|
||
/// | ||
ref inout(T) front() inout nothrow @safe @nogc { static if (N > 0) { return this[0]; } else { return as_array()[][0]; /* HACK: force OOB */ } } | ||
/// | ||
ref inout(T) back() inout nothrow @safe @nogc { static if (N > 0) { return this[N-1]; } else { return as_array()[][0]; /* HACK: force OOB */ } } | ||
|
||
/// | ||
void fill()(auto ref const(T) value) { this[] = value; } | ||
|
||
version (CppRuntime_Windows) | ||
{ | ||
/// | ||
inout(T)* data() inout nothrow @safe @nogc { return &_Elems[0]; } | ||
/// | ||
ref inout(T)[N] as_array() const inout @safe @nogc { return _Elems[0 .. N]; } | ||
/// | ||
ref inout(T) at(size_type i) inout nothrow @safe @nogc { return _Elems[0 .. N][i]; } | ||
|
||
version (CppRuntime_Microsoft) | ||
{ | ||
import core.stdcpp.xutility : MSVCLinkDirectives; | ||
mixin MSVCLinkDirectives!false; | ||
} | ||
|
||
private: | ||
T[N ? N : 1] _Elems; | ||
} | ||
else version (CppRuntime_Gcc) | ||
{ | ||
/// | ||
inout(T)* data() inout nothrow @safe @nogc { static if (N > 0) { return &_M_elems[0]; } else { return null; } } | ||
/// | ||
ref inout(T)[N] as_array() inout nothrow @trusted @nogc { return data()[0 .. N]; } | ||
/// | ||
ref inout(T) at(size_type i) inout nothrow @trusted @nogc { return data()[0 .. N][i]; } | ||
|
||
private: | ||
static if (N > 0) | ||
{ | ||
T[N] _M_elems; | ||
} | ||
else | ||
{ | ||
struct _Placeholder {} | ||
_Placeholder _M_placeholder; | ||
} | ||
} | ||
else version (CppRuntime_Clang) | ||
{ | ||
/// | ||
inout(T)* data() inout nothrow @trusted @nogc { static if (N > 0) { return &__elems_[0]; } else { return cast(inout(T)*)__elems_.ptr; } } | ||
/// | ||
ref inout(T)[N] as_array() inout nothrow @trusted @nogc { return data()[0 .. N]; } | ||
/// | ||
ref inout(T) at(size_type i) inout nothrow @trusted @nogc { return data()[0 .. N][i]; } | ||
|
||
private: | ||
static if (N > 0) | ||
{ | ||
T[N] __elems_; | ||
} | ||
else | ||
{ | ||
struct _ArrayInStructT { T[1] __data_; } | ||
align(_ArrayInStructT.alignof) | ||
byte[_ArrayInStructT.sizeof] __elems_ = void; | ||
} | ||
} | ||
else | ||
{ | ||
static assert(false, "C++ runtime not supported"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
/** | ||
* D header file for interaction with Microsoft C++ <xutility> | ||
* | ||
* Copyright: Copyright (c) 2018 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/xutility.d) | ||
*/ | ||
|
||
module core.stdcpp.xutility; | ||
|
||
extern(C++, "std"): | ||
|
||
version (CppRuntime_Microsoft) | ||
{ | ||
// Client code can mixin the set of MSVC linker directives | ||
mixin template MSVCLinkDirectives(bool failMismatch = false) | ||
{ | ||
import core.stdcpp.xutility : __CXXLIB__; | ||
|
||
static if (__CXXLIB__ == "libcmtd") | ||
{ | ||
pragma(lib, "libcpmtd"); | ||
static if (failMismatch) | ||
pragma(linkerDirective, "/FAILIFMISMATCH:RuntimeLibrary=MTd_StaticDebug"); | ||
} | ||
else static if (__CXXLIB__ == "msvcrtd") | ||
{ | ||
pragma(lib, "msvcprtd"); | ||
static if (failMismatch) | ||
pragma(linkerDirective, "/FAILIFMISMATCH:RuntimeLibrary=MDd_DynamicDebug"); | ||
} | ||
else static if (__CXXLIB__ == "libcmt") | ||
{ | ||
pragma(lib, "libcpmt"); | ||
static if (failMismatch) | ||
pragma(linkerDirective, "/FAILIFMISMATCH:RuntimeLibrary=MT_StaticRelease"); | ||
} | ||
else static if (__CXXLIB__ == "msvcrt") | ||
{ | ||
pragma(lib, "msvcprt"); | ||
static if (failMismatch) | ||
pragma(linkerDirective, "/FAILIFMISMATCH:RuntimeLibrary=MD_DynamicRelease"); | ||
} | ||
} | ||
|
||
// convenient alias for the C++ std library name | ||
enum __CXXLIB__ = __traits(getTargetInfo, "cppRuntimeLibrary"); | ||
|
||
package: | ||
// these are all [[noreturn]] | ||
void _Xbad() nothrow @trusted @nogc; | ||
void _Xinvalid_argument(const(char)* message) nothrow @trusted @nogc; | ||
void _Xlength_error(const(char)* message) nothrow @trusted @nogc; | ||
void _Xout_of_range(const(char)* message) nothrow @trusted @nogc; | ||
void _Xoverflow_error(const(char)* message) nothrow @trusted @nogc; | ||
void _Xruntime_error(const(char)* message) nothrow @trusted @nogc; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
include ../common.mak | ||
|
||
TESTS:=array | ||
|
||
.PHONY: all clean | ||
|
||
# osx32 does not link properly, nobody uses it anyway... | ||
ifeq ($(OS)$(MODEL), osx32) | ||
|
||
all: | ||
|
||
clean: | ||
|
||
else | ||
all: $(addprefix $(ROOT)/,$(addsuffix .done,$(TESTS))) | ||
|
||
$(ROOT)/%.done : $(ROOT)/% | ||
@echo Testing $* | ||
$(QUIET)$(TIMELIMIT)$(ROOT)/$* $(RUN_ARGS) | ||
@touch $@ | ||
|
||
$(ROOT)/%: $(SRC)/%_test.d $(SRC)/%.cpp | ||
mkdir -p $(dir $@) | ||
$(QUIET)$(CXX) $(CXXFLAGS) -c -o $(ROOT)/$*_cpp.o $(SRC)/$*.cpp | ||
$(QUIET)$(DMD) $(DFLAGS) -main -unittest -of$@ $< $(ROOT)/$*_cpp.o | ||
|
||
clean: | ||
rm -rf $(GENERATED) | ||
endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#include <array> | ||
|
||
std::array<int, 5> fromC_val(std::array<int, 5>); | ||
std::array<int, 5>& fromC_ref(std::array<int, 5>&); | ||
|
||
std::array<int, 5>& sumOfElements_ref(std::array<int, 5>& arr) | ||
{ | ||
int r = 0; | ||
for (size_t i = 0; i < arr.size(); ++i) | ||
r += arr[i]; | ||
arr.fill(r); | ||
return arr; | ||
} | ||
|
||
std::array<int, 5> sumOfElements_val(std::array<int, 5> arr) | ||
{ | ||
int r = sumOfElements_ref(arr)[0] + fromC_ref(arr)[0] + fromC_val(arr)[0]; | ||
arr.fill(r); | ||
return arr; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import core.stdcpp.array; | ||
|
||
extern (C++) int test_array() | ||
{ | ||
array!(int, 5) arr; | ||
arr[] = [0, 2, 3, 4, 5]; | ||
++arr.front; | ||
|
||
assert(arr.size == 5); | ||
assert(arr.length == 5); | ||
assert(arr.max_size == 5); | ||
assert(arr.empty == false); | ||
assert(arr.front == 1); | ||
|
||
assert(sumOfElements_val(arr)[0] == 160); | ||
assert(sumOfElements_ref(arr)[0] == 15); | ||
|
||
array!(int, 0) arr2; | ||
assert(arr2.size == 0); | ||
assert(arr2.length == 0); | ||
assert(arr2.max_size == 0); | ||
assert(arr2.empty == true); | ||
assert(arr2[] == []); | ||
|
||
return 0; | ||
} | ||
|
||
|
||
extern(C++): | ||
|
||
// test the ABI for calls to C++ | ||
array!(int, 5) sumOfElements_val(array!(int, 5) arr); | ||
ref array!(int, 5) sumOfElements_ref(return ref array!(int, 5) arr); | ||
|
||
// test the ABI for calls from C++ | ||
array!(int, 5) fromC_val(array!(int, 5) arr) | ||
{ | ||
assert(arr[] == [1, 2, 3, 4, 5]); | ||
assert(arr.front == 1); | ||
assert(arr.back == 5); | ||
assert(arr.at(2) == 3); | ||
|
||
arr.fill(2); | ||
|
||
int r; | ||
foreach (e; arr) | ||
r += e; | ||
|
||
assert(r == 10); | ||
|
||
arr[] = r; | ||
return arr; | ||
} | ||
|
||
ref array!(int, 5) fromC_ref(return ref array!(int, 5) arr) | ||
{ | ||
int r; | ||
foreach (e; arr) | ||
r += e; | ||
arr[] = r; | ||
return arr; | ||
} |
Oops, something went wrong.