THRIFT-2770 thrift.internal.traits unittest fails due to std.metastrings import
Client: D
Patch: David Nadlinger

This closes #237

I originally wrote what became std.traits.SetFunctionAttributes as thrift.internal.traits.ChangeFuncAttrs. Now that it has been in Phobos for a number of releases, remove the local copy. This is both a cleanup and fixes the -unittest build in 2.066, where std.metastrings (which was just a stray import anyway) has finally been removed.
diff --git a/lib/d/src/thrift/internal/traits.d b/lib/d/src/thrift/internal/traits.d
index 11e98c5..8ce1089 100644
--- a/lib/d/src/thrift/internal/traits.d
+++ b/lib/d/src/thrift/internal/traits.d
@@ -21,115 +21,6 @@
 import std.traits;
 
 /**
- * Adds or removes attributes from the given function (pointer) or delegate
- * type.
- *
- * Besides the base type, two std.traits.FunctionAttribute bitfields are
- * accepted, representing the attributes to add to the function signature
- * resp. to remove from it. If an attribute appears in both fields, an error
- * is raised.
- *
- * Params:
- *   T = The base type.
- *   setAttrs = The attributes to add to the type, if not already present.
- *   clearAttrs = The attributes to remove from the type, if present.
- */
-template ChangeFuncAttrs(
-  T,
-  FunctionAttribute setAttrs = FunctionAttribute.none,
-  FunctionAttribute clearAttrs = FunctionAttribute.none
-) if (isFunctionPointer!T || isDelegate!T) {
-  static assert(!(setAttrs & clearAttrs),
-    "Cannot set and clear attributes at the same time.");
-  mixin({
-    enum newAttrs = (functionAttributes!T | setAttrs) & ~clearAttrs;
-    static assert(!(newAttrs & FunctionAttribute.trusted) ||
-      !(newAttrs & FunctionAttribute.safe),
-      "Cannot have a function/delegate that is both trusted and safe.");
-
-    string result = "alias ";
-
-    static if (functionLinkage!T != "D") {
-      result ~= "extern(" ~ functionLinkage!T ~ ") ";
-    }
-
-    static if (newAttrs & FunctionAttribute.ref_) {
-      result ~= "ref ";
-    }
-
-    result ~= "ReturnType!T";
-
-    static if (isDelegate!T) {
-      result ~= " delegate";
-    } else {
-      result ~= " function";
-    }
-
-    result ~= "(ParameterTypeTuple!T)";
-
-    static if (newAttrs & FunctionAttribute.pure_) {
-      result ~= " pure";
-    }
-    static if (newAttrs & FunctionAttribute.nothrow_) {
-      result ~= " nothrow";
-    }
-    static if (newAttrs & FunctionAttribute.property) {
-      result ~= " @property";
-    }
-    static if (newAttrs & FunctionAttribute.trusted) {
-      result ~= " @trusted";
-    }
-    static if (newAttrs & FunctionAttribute.safe) {
-      result ~= " @safe";
-    }
-
-    result ~= " ChangeFuncAttrs;";
-    return result;
-  }());
-}
-
-/// Ditto
-template ChangeFuncAttrs(
-  T,
-  FunctionAttribute setAttrs = FunctionAttribute.none,
-  FunctionAttribute clearAttrs = FunctionAttribute.none
-) if (is(T == function)) {
-  // To avoid a lot of syntactic headaches, we just use the above version to
-  // operate on the corresponding function pointer type and then remove the
-  // pointer again.
-  alias FunctionTypeOf!(ChangeFuncAttrs!(T*, setAttrs, clearAttrs))
-    ChangeFuncAttrs;
-}
-
-version (unittest) {
-  import std.algorithm;
-  import std.metastrings;
-  import std.typetuple;
-}
-unittest {
-  alias FunctionAttribute FA;
-  foreach (T0; TypeTuple!(
-    int function(int),
-    int delegate(int),
-    FunctionTypeOf!(int function(int))
-  )) {
-    alias ChangeFuncAttrs!(T0, FA.safe) T1;
-    static assert(functionAttributes!T1 == FA.safe);
-
-    alias ChangeFuncAttrs!(T1, FA.nothrow_ | FA.ref_, FA.safe) T2;
-    static assert(functionAttributes!T2 == (FA.nothrow_ | FA.ref_));
-
-    enum allAttrs = reduce!"a | b"([EnumMembers!FA]) & ~FA.safe;
-
-    alias ChangeFuncAttrs!(T2, allAttrs) T3;
-    static assert(functionAttributes!T3 == allAttrs);
-
-    alias ChangeFuncAttrs!(T3, FA.none, allAttrs) T4;
-    static assert(is(T4 == T0));
-  }
-}
-
-/**
  * Adds »nothrow« to the type of the passed function pointer/delegate, if it
  * is not already present.
  *
@@ -137,5 +28,6 @@
  * advantage of being explicitly about the operation that is performed.
  */
 auto assumeNothrow(T)(T t) if (isFunctionPointer!T || isDelegate!T) {
-  return cast(ChangeFuncAttrs!(T, FunctionAttribute.nothrow_))t;
+  enum attrs = functionAttributes!T | FunctionAttribute.nothrow_;
+  return cast(SetFunctionAttributes!(T, functionLinkage!T, attrs)) t;
 }