diff --git a/posix.mak b/posix.mak index ada95490b..0f7e11220 100644 --- a/posix.mak +++ b/posix.mak @@ -216,7 +216,7 @@ EXTRA_MODULES_INTERNAL := $(addprefix \ std/internal/digest/, sha_SSSE3 ) $(addprefix \ std/internal/math/, biguintcore biguintnoasm biguintx86 \ gammafunction errorfunction) $(addprefix std/internal/, \ - cstring phobosinit processinit unicode_tables scopebuffer\ + cstring encodinginit processinit unicode_tables scopebuffer\ unicode_comp unicode_decomp unicode_grapheme unicode_norm) \ $(addprefix std/internal/test/, dummyrange) \ $(addprefix std/experimental/ndslice/, internal) \ diff --git a/std/encoding.d b/std/encoding.d index 84879b094..427087b31 100644 --- a/std/encoding.d +++ b/std/encoding.d @@ -55,6 +55,7 @@ module std.encoding; import std.traits; import std.typecons; import std.range.primitives; +import std.internal.encodinginit; @system unittest { @@ -2360,17 +2361,30 @@ abstract class EncodingScheme * This function allows user-defined subclasses of EncodingScheme to * be declared in other modules. * + * Params: + * Klass = The subclass of EncodingScheme to register. + * * Example: * ---------------------------------------------- * class Amiga1251 : EncodingScheme * { * shared static this() * { - * EncodingScheme.register("path.to.Amiga1251"); + * EncodingScheme.register!Amiga1251; * } * } * ---------------------------------------------- */ + static void register(Klass:EncodingScheme)() + { + scope scheme = new Klass(); + foreach (encodingName;scheme.names()) + { + supported[toLower(encodingName)] = () => new Klass(); + } + } + + deprecated("Please pass the EncodingScheme subclass as template argument instead.") static void register(string className) { auto scheme = cast(EncodingScheme)ClassInfo.find(className).create(); @@ -2378,7 +2392,7 @@ abstract class EncodingScheme throw new EncodingException("Unable to create class "~className); foreach (encodingName;scheme.names()) { - supported[toLower(encodingName)] = className; + supportedFactories[toLower(encodingName)] = className; } } @@ -2396,7 +2410,12 @@ abstract class EncodingScheme */ static EncodingScheme create(string encodingName) { - auto p = toLower(encodingName) in supported; + encodingName = toLower(encodingName); + + if (auto p = encodingName in supported) + return (*p)(); + + auto p = encodingName in supportedFactories; if (p is null) throw new EncodingException("Unrecognized Encoding: "~encodingName); string className = *p; @@ -2650,7 +2669,8 @@ abstract class EncodingScheme return t.length - s.length; } - __gshared string[string] supported; + __gshared EncodingScheme function()[string] supported; + __gshared string[string] supportedFactories; } /** @@ -3297,6 +3317,20 @@ class EncodingSchemeUtf32Native : EncodingScheme assert(ub.length == 8); } + +// shared static this() called from encodinginit to break ctor cycle +extern(C) void std_encoding_shared_static_this() +{ + EncodingScheme.register!EncodingSchemeASCII; + EncodingScheme.register!EncodingSchemeLatin1; + EncodingScheme.register!EncodingSchemeLatin2; + EncodingScheme.register!EncodingSchemeWindows1250; + EncodingScheme.register!EncodingSchemeWindows1252; + EncodingScheme.register!EncodingSchemeUtf8; + EncodingScheme.register!EncodingSchemeUtf16Native; + EncodingScheme.register!EncodingSchemeUtf32Native; +} + //============================================================================= diff --git a/std/internal/encodinginit.d b/std/internal/encodinginit.d new file mode 100644 index 000000000..837e46492 --- /dev/null +++ b/std/internal/encodinginit.d @@ -0,0 +1,19 @@ +// Written in the D programming language. + +/++ + The purpose of this module is to perform static construction away from the + normal modules to eliminate cyclic construction errors. + + Copyright: Copyright 2011 - 2016 + License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). + Authors: Martin Nowak, Steven Schveighoffer + Source: $(PHOBOSSRC std/internal/_encodinginit.d) + +/ +module std.internal.encodinginit; + +extern(C) void std_encoding_shared_static_this(); + +shared static this() +{ + std_encoding_shared_static_this(); +} diff --git a/std/internal/phobosinit.d b/std/internal/phobosinit.d deleted file mode 100644 index 85fd1c25d..000000000 --- a/std/internal/phobosinit.d +++ /dev/null @@ -1,25 +0,0 @@ -// Written in the D programming language. - -/++ - The purpose of this module is to perform static construction away from the - normal modules to eliminate cyclic construction errors. - - Copyright: Copyright 2011 - 2016 - License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - Authors: Jonathan M Davis, Kato Shoichi, Steven Schveighoffer - Source: $(PHOBOSSRC std/internal/_phobosinit.d) - +/ -module std.internal.phobosinit; - -shared static this() -{ - import std.encoding : EncodingScheme; - EncodingScheme.register("std.encoding.EncodingSchemeASCII"); - EncodingScheme.register("std.encoding.EncodingSchemeLatin1"); - EncodingScheme.register("std.encoding.EncodingSchemeLatin2"); - EncodingScheme.register("std.encoding.EncodingSchemeWindows1250"); - EncodingScheme.register("std.encoding.EncodingSchemeWindows1252"); - EncodingScheme.register("std.encoding.EncodingSchemeUtf8"); - EncodingScheme.register("std.encoding.EncodingSchemeUtf16Native"); - EncodingScheme.register("std.encoding.EncodingSchemeUtf32Native"); -} diff --git a/win32.mak b/win32.mak index 793035487..6c4e92ebe 100644 --- a/win32.mak +++ b/win32.mak @@ -267,7 +267,7 @@ SRC_STD_C_FREEBSD= \ SRC_STD_INTERNAL= \ std\internal\cstring.d \ - std\internal\phobosinit.d \ + std\internal\encodinginit.d \ std\internal\processinit.d \ std\internal\unicode_tables.d \ std\internal\unicode_comp.d \ diff --git a/win64.mak b/win64.mak index 56df482e2..df4e1abbe 100644 --- a/win64.mak +++ b/win64.mak @@ -286,7 +286,7 @@ SRC_STD_C_FREEBSD= \ SRC_STD_INTERNAL= \ std\internal\cstring.d \ - std\internal\phobosinit.d \ + std\internal\encodinginit.d \ std\internal\processinit.d \ std\internal\unicode_tables.d \ std\internal\unicode_comp.d \