From a94b1b0af46f69216b6c78ced37de80dc2ffae24 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Sat, 7 Jul 2018 12:17:59 +0200 Subject: [PATCH] Add functional module. Fix #52 --- .travis.yml | 3 +- README.md | 5 ++- appveyor.yml | 6 ++++ source/tanya/functional.d | 71 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 source/tanya/functional.d diff --git a/.travis.yml b/.travis.yml index b0cb77f..20b547d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,7 @@ os: language: d d: + - dmd-2.081.0 - dmd-2.080.1 - dmd-2.079.1 - dmd-2.078.3 @@ -23,7 +24,7 @@ addons: - gcc-multilib before_script: - - if [ "`$DC --version | head -n 1 | grep 'v2.080.1'`" ]; then + - if [ "`$DC --version | head -n 1 | grep 'v2.081.0'`" ]; then export UNITTEST="unittest-cov"; fi diff --git a/README.md b/README.md index a6867ab..dbf2109 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,8 @@ types. * `encoding`: This package provides tools to work with text encodings. * `exception`: Common exceptions and errors. * `format`: Formatting and conversion functions. +* `functional`: Functions that manipulate other functions and their argument +lists. * `hash`: Hash algorithms. * `math`: Arbitrary precision integer and a set of functions. * `memory`: Tools for manual memory management (allocators, smart pointers). @@ -172,7 +174,8 @@ parameter is used) | DMD | GCC | |:-------:|:---------:| -| 2.080.1 | *master* | +| 2.081.0 | *master* | +| 2.080.1 | | | 2.079.1 | | | 2.078.3 | | | 2.077.1 | | diff --git a/appveyor.yml b/appveyor.yml index 7d10c0b..2da2d02 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -3,6 +3,12 @@ os: Visual Studio 2015 environment: matrix: + - DC: dmd + DVersion: 2.081.0 + arch: x64 + - DC: dmd + DVersion: 2.081.0 + arch: x86 - DC: dmd DVersion: 2.080.1 arch: x64 diff --git a/source/tanya/functional.d b/source/tanya/functional.d new file mode 100644 index 0000000..3b5adf5 --- /dev/null +++ b/source/tanya/functional.d @@ -0,0 +1,71 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * Functions that manipulate other functions and their argument lists. + * + * Copyright: Eugene Wissner 2018. + * License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/, + * Mozilla Public License, v. 2.0). + * Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner) + * Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/source/tanya/functional.d, + * tanya/functional.d) + */ +module tanya.functional; + +import tanya.algorithm.mutation; +import tanya.meta.metafunction; + +private template forwardOne(alias arg) +{ + static if (__traits(isRef, arg) || __traits(isOut, arg)) + { + alias forwardOne = arg; + } + else + { + @property auto forwardOne() + { + return move(arg); + } + } +} + +/** + * Forwards its argument list preserving $(D_KEYWORD ref) and $(D_KEYWORD out) + * storage classes. + * + * $(D_PSYMBOL forward) accepts a list of variables or literals. It returns an + * argument list of the same length that can be for example passed to a + * function accepting the arguments of this type. + * + * Params: + * args = Argument list. + * + * Returns: $(D_PARAM args) with their original storage classes. + */ +template forward(args...) +{ + static if (args.length == 1) + { + alias forward = forwardOne!(args[0]); + } + else + { + alias forward = Map!(forwardOne, args); + } +} + +/// +@nogc nothrow pure @safe unittest +{ + static assert(is(typeof((int i) { int v = forward!i; }))); + static assert(is(typeof((ref int i) { int v = forward!i; }))); + static assert(is(typeof({ + void f(int i, ref int j, out int k) + { + f(forward!(i, j, k)); + } + }))); +}