From dba38b5640f120b92e39c7a9eafdb7aef4c20533 Mon Sep 17 00:00:00 2001 From: Andrei Alexandrescu Date: Sun, 11 Jun 2017 14:39:41 -0400 Subject: [PATCH] Revert "reimplement std.traits.ParameterStorageClassTuple()" --- std/traits.d | 81 +++++++++++++++++++--------------------------------- 1 file changed, 30 insertions(+), 51 deletions(-) diff --git a/std/traits.d b/std/traits.d index 91b4d015b21..506dd3ffeaf 100644 --- a/std/traits.d +++ b/std/traits.d @@ -1010,11 +1010,8 @@ template arity(alias func) } /** -Get tuple, one per function parameter, of the storage classes of the parameters. -Params: - func = function symbol or type of function, delegate, or pointer to function -Returns: - a tuple of ParameterStorageClass bits +Returns a tuple consisting of the storage classes of the parameters of a +function $(D func). */ enum ParameterStorageClass : uint { @@ -1034,28 +1031,39 @@ enum ParameterStorageClass : uint template ParameterStorageClassTuple(func...) if (func.length == 1 && isCallable!func) { - alias Func = FunctionTypeOf!func; + alias Func = Unqual!(FunctionTypeOf!func); - static if (is(Func PT == __parameters)) + /* + * TypeFuncion: + * CallConvention FuncAttrs Arguments ArgClose Type + */ + alias Params = Parameters!Func; + + // chop off CallConvention and FuncAttrs + enum margs = demangleFunctionAttributes(mangledName!Func[1 .. $]).rest; + + // demangle Arguments and store parameter storage classes in a tuple + template demangleNextParameter(string margs, size_t i = 0) { - template StorageClass(size_t i) + static if (i < Params.length) { - static if (i < PT.length) - { - alias StorageClass = TypeTuple!( - extractParameterStorageClassFlags!(__traits(getParameterStorageClasses, Func, i)), - StorageClass!(i + 1)); - } - else - alias StorageClass = TypeTuple!(); + enum demang = demangleParameterStorageClass(margs); + enum skip = mangledName!(Params[i]).length; // for bypassing Type + enum rest = demang.rest; + + alias demangleNextParameter = + TypeTuple!( + demang.value + 0, // workaround: "not evaluatable at ..." + demangleNextParameter!(rest[skip .. $], i + 1) + ); + } + else // went thru all the parameters + { + alias demangleNextParameter = TypeTuple!(); } - alias ParameterStorageClassTuple = StorageClass!0; - } - else - { - static assert(0, func[0].stringof ~ " is not a function"); - alias ParameterStorageClassTuple = TypeTuple!(); } + + alias ParameterStorageClassTuple = demangleNextParameter!margs; } /// @@ -1073,35 +1081,6 @@ template ParameterStorageClassTuple(func...) static assert(pstc[2] == STC.none); } -/***************** - * Convert string tuple Attribs to ParameterStorageClass bits - * Params: - * Attribs = string tuple - * Returns: - * ParameterStorageClass bits - */ -ParameterStorageClass extractParameterStorageClassFlags(Attribs...)() -{ - auto result = ParameterStorageClass.none; - foreach (attrib; Attribs) - { - final switch (attrib) with (ParameterStorageClass) - { - case "scope": result |= scope_; break; - case "out": result |= out_; break; - case "ref": result |= ref_; break; - case "lazy": result |= lazy_; break; - case "return": result |= return_; break; - } - } - /* Mimic behavor of original version of ParameterStorageClassTuple() - * to avoid breaking existing code. - */ - if (result == (ParameterStorageClass.ref_ | ParameterStorageClass.return_)) - result = ParameterStorageClass.return_; - return result; -} - @safe unittest { alias STC = ParameterStorageClass;